2010-08-25 9 views
6

Ho un sacco di gente NSManagedObjects che ho bisogno di filtrare e speravo di farlo nel recupero iniziale invece di filtrare l'array in seguito. Sono selettori usati in predicati prima, ma mai quando il recupero NSManagedObjects, per esempio ho tutti i miei dipendenti e poi io uso questo predicato sulla NSArray ...NSPredicate con funzioni o selettori

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

... ma ora voglio fare un po 'più di matematica basata su diversi attributi dei miei oggetti. Ho pensato che avrei potuto fare qualcosa di simile ...

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

..dove bonusIsAffordable: è un metodo della mia classe Employee e sarebbe calcolare se posso permettermi di pagare loro un bonus. Ma ottengo un errore ...

Unknown/unsupported comparison predicate operator type cocoa 

Qualche idea su cosa sto rovinando?

risposta

13

È possibile eseguire codice arbitrario in un NSPredicate solo oggetti prima sessione di qualifica in memoria. Nel caso di uno NSPersistentStore supportato da SQLite, lo NSPredicate viene compilato su SQL ed eseguito sul motore di query SQLite. Dato che SQLite non ha conoscenza di Objective-C, né gli oggetti sono istanziati, non c'è modo di eseguire codice arbitrario.

Per le query in memoria (contro una raccolta o un in-memoria o atomica negozio di dati Core), uno sguardo a NSExpression, particolare +[NSExpression expressionForFunction:selectorName:arguments:] e +[NSExpression expressionForBlock:arguments:]. Data tale espressione, è possibile creare un NSPredicate in modo programmatico.

+0

OK, questo ha senso. Mi stavo chiedendo come avrebbe funzionato usando SELF ogni volta. Immaginavo che avrebbe tirato ogni oggetto in memoria, ho sbagliato. – rob5408

0

La stringa del predicato non indica all'oggetto del predicato cosa fare. Il metodo restituisce presumibilmente un valore booleano ma il predicato non sa a cosa paragonarlo. Si potrebbe anche aver dato una stringa di predicato di "VERO" e si aspettava che sapesse cosa farne.

Prova:

[NSPredicate predicateWithFormat:@"(SELF bonusIsAffordable:%f)==YES", howMuchMoneyTheCompanyHas]; 
+0

OK, dato che un colpo e ottenuto 'Impossibile analizzare la stringa di formato "(AUTO bonusIsAffordable:% f) == SI"'. Inoltre, assegnargli una stringa di predicato true funzionerebbe, proprio come "(SELF bonusIsAffordable:% f) == YES" teoricamente valuterà in booleano e "SELF isKindOfClass:% @" si valuta in booleano, no? – rob5408

14

Questo diventa molto più semplice con Blocks:

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

    return [evaluatedObject isKindOfClass:[Boss class]]; 
}]; 
+0

E se fosse necessario farlo in modo sincrono? – zakdances

+2

Questo non funziona in iOS con archivio persistente – Krishnan