Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSPredicate with functions or selectors

I have a lot of people NSManagedObjects that I need filtering and was hoping to do it within the initial fetch instead of filtering the array afterwards. I've used selectors in predicates before, but never when fetching NSManagedObjects, for example I have all my employees and then i use this predicate on the NSArray...

[NSPredicate predicateWithFormat:@"SELF isKindOfClass:%@", [Boss class]]

...but now I want to do a bit more math based on different attributes of my objects. I thought I could do something like...

[NSPredicate predicateWithFormat:@"SELF bonusIsAffordable:%f", howMuchMoneyTheCompanyHas];

..where bonusIsAffordable: is a method of my Employee class and would calculate whether I can afford to pay them a bonus. But I get an error...

Unknown/unsupported comparison predicate operator type cocoa

Any ideas what I'm screwing up?

like image 211
rob5408 Avatar asked Aug 25 '10 19:08

rob5408


2 Answers

This gets a whole lot easier with Blocks:

NSPredicate *bossPred = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {

    return [evaluatedObject isKindOfClass:[Boss class]];
}];
like image 194
Daniel Avatar answered Nov 08 '22 10:11

Daniel


You can execute arbitrary code in an NSPredicate only when qualifying objects in memory. In the case of a SQLite-backed NSPersistentStore, the NSPredicate is compiled to SQL and executed on the SQLite query engine. Since SQLite has no knowlege of Objective-C, nor are any objects instantiated, there's no way to execute arbitrary code.

For in-memory queries (against a collection or an in-memory or atomic Core Data store), have a look at NSExpression, particular +[NSExpression expressionForFunction:selectorName:arguments:] and +[NSExpression expressionForBlock:arguments:]. Given such an expression, you can build an NSPredicate programatically.

like image 13
Barry Wark Avatar answered Nov 08 '22 10:11

Barry Wark