NSFetchRequest e predicateWithBlock

Sto giocando con un’app che utilizza Core Data e NSManagedObjects per popolare UITableView. C’è solo una class nella mia applicazione, chiamata Event . Ho creato il seguente metodo di istanza personalizzato su Event :

 - (BOOL)isExpired { return ([[self.endOn dateAtEndOfDay] timeIntervalSinceNow] < 0); } 

Vorrei limitare UITableView che visualizza gli oggetti Event solo agli eventi che sono scaduti, ovvero, dove isExpired restituisce YES . Ho provato a farlo aggiungendo un NSPredicate a NSFetchRequest :

 NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary * bindings) {return([evaluatedObject isExpired]);}]; [fetchRequest setPredicate:predicate]; 

ma ottengo l’errore: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Problem with subpredicate BLOCKPREDICATE(0x272ac)' *** . Questo significa che non è ansible utilizzare un predicato di blocco con NSFetchRequest? O l’ho appena costruito in modo improprio?

Grazie!

Pertanto, sembra che nei commenti al post originale sia stato stabilito che questo è probabilmente causato dagli store SQLite che sono incompatibili con i predicati dei blocchi, poiché i Core Data non possono tradurli in SQL per eseguirli nell’archivio (grazie, JoostK).

Ci potrebbero essere un paio di modi per superare questo:

  • A condizione che la data di fine delle entity framework sia un attributo regolare, potrebbe essere ansible esprimere il limite di scadenza come una stringa di formato di predicato anziché un predicato di blocco, che i dati di base dovrebbero essere in grado di tradurre in una clausola SQL.
  • Se quanto sopra è ansible, probabilmente preferirai utilizzare un modello di richiesta di recupero per recuperare gli elementi scaduti. Dovresti passare una variabile sostitutiva come $NOW per dare accesso alla data corrente, però. Questo ha il vantaggio di mostrare il modello di predicato nell’editor del modello.
  • Entrambi gli approcci, tuttavia, hanno lo svantaggio di duplicare la funzionalità esistente (ad esempio, il metodo isExpired ). Quindi un altro modo sarebbe recuperare tutte le entity framework qualificanti, indipendentemente dal loro stato di scadenza, e poi eseguire un passaggio di filtraggio dedicato sul gruppo risultante di entity framework per estirpare quelle non scadute. Da quel momento, sono stati completamente resuscitati dal negozio, dovresti essere in grado di utilizzare un predicato di blocco per questo.

È ansible eseguire una richiesta di recupero normale senza specificare il predicato e successivamente filtrare l’array risultante:

 NSArray *allEvents = [context executeFetchRequest:fetchRequest]; if (!allEvents) { // do error handling here } NSArray *expiredEvents = [allEvents filteredArrayUsingPredicate:predicate];