3

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 ?

netmajor
  • 6,507
  • 14
  • 68
  • 100

2 Answers2

8

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;
}];
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

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.

Vincent Bernier
  • 8,674
  • 4
  • 35
  • 40