Core Data NSPredicate “cancellato == NO” non funziona come previsto

Sto usando UIManagedDocument con il contesto Parent Child.

Nel mio contesto figlio faccio quanto segue

Codice 1

NSSet *results = [self.event.memberships filteredSetUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) { return ([[evaluatedObject deleted] boolValue] == NO); }]]; 

Sopra il codice restituisce i risultati previsti (solo membri non cancellati per l’evento).

Codice 2

Ma questo codice no. Raccoglie tutti i record.

 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"deleted == NO"]; NSSet *results = [self.event.memberships filteredSetUsingPredicate:predicate]; 

Sembra confusionario. Entrambi dovrebbero restituire gli stessi risultati, ma predicateWithBlock restituisce risultati corretti laddove predicateWithFormat restituisce tutti i record.

Quali sono i pro e i contro dell’utilizzo di predicateWithBlock anziché predicateWithFormat ?

Il problema è che hai definito un attributo deleted per la tua quadro. Ciò è in conflitto con il metodo isDeleted di NSManagedObject , quindi è necessario rinominare tale attributo.

Il seguente “esperimento” mostra che accadono cose strane se chiami il tuo attributo “cancellato” ( c è un object gestito con un attributo personalizzato deleted ):

 // Set custom "deleted" property to YES: c.deleted = @YES; // Use the property, as your Code 1 NSLog(@"%@", [c deleted]); // Output: 1 // Use Key-Value Coding, as your Code 2 NSLog(@"%@", [c valueForKey:@"deleted"]); // Output: 0 // Now really delete the object and try again: [context deleteObject:c]; NSLog(@"%@", [c valueForKey:@"deleted"]); // Output: 1 

Il tuo “Codice 1” si riferisce alla proprietà, pertanto restituisce il risultato previsto. “Codice 2” utilizza la codifica dei valori-chiave e [c valueForKey:@"deleted"] restituisce YES se l’object è stato effettivamente eliminato dal contesto!

Quindi rinominare quell’attributo dovrebbe risolvere il tuo problema. Sfortunatamente il compilatore non emette avvisi se il nome di un attributo è in conflitto con un metodo integrato.

Usa il segnaposto di formattazione per sostituire il valore bool:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"deleted", @(NO)];

Il tuo utilizzo del percorso chiave è probabilmente ok, ma il lato destro probabilmente non sembra “NO” al parser.