views:

57

answers:

2

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?

A: 

Your predicate string doesn't tell the predicate object what to do. The method presumably returns a boolean but the predicate doesn't know what to compare that to. You might as well have given it a predicate string of "TRUE" and expected it to know what to do with it.

Try:

[NSPredicate predicateWithFormat:@"(SELF bonusIsAffordable:%f)==YES", howMuchMoneyTheCompanyHas];
TechZen
OK, gave that a shot and got 'Unable to parse the format string "(SELF bonusIsAffordable:%f)==YES"'. Also, giving it a predicate string of true would work, just as "(SELF bonusIsAffordable:%f)==YES" theoretically would evaluate to boolean and "SELF isKindOfClass:%@" evaluates to boolean, no?
rob5408
+4  A: 

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.

Barry Wark
OK, that makes sense. I was wondering how it was going to go about using SELF each time. I assumed it would pull each object into memory, I assumed wrong.
rob5408