3
votes

I have that class :

@interface Field : NSObject
@property CGPoint fieldCoordinates;
@property CGPoint ballCoordinates;
@end

and i Try filter NSArray of object of this class :

NSPredicate * y1 = [NSPredicate predicateWithFormat:@"ballCoordinates.y >= %@",location.y];
NSArray * filtered = [self.fieldsArray filteredArrayUsingPredicate:y1];

but get error :

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ valueForUndefinedKey:]: this class is not key value coding-compliant for the key y.'

NSPredicate have problem with filter by CGPoint ?

2

2 Answers

8
votes

Yes, NSPredicate has problems with CGPoint, because it is a struct, not a key-value compliant Objective-C class. You can write a predicate with a block instead, like this:

NSPredicate * y1 = [NSPredicate predicateWithBlock: ^BOOL(id obj, NSDictionary *bind) {
    return ((CGPoint)[obj ballCoordinates]).y >= location.y;
}];
1
votes

CGPoint is not an Object it's a plain old C struct.
You could walk around that by making a readonly property on your Field class that look like this. @property (nonatomic, readonly) CGFloat yBallCoordinates;
- (CGFloat)yBallCoordinates { return self.ballCoordinates.y; }


Edit
The block approach pointed by dasblinkenlight is a better solution.
Because it will not involve the necessity of declaring property for every thing you want to predicate on. Which will be more flexible.