objective-c core-data nspredicate uimanageddocument

objective c - Core Data NSPredicate "deleted== NO" no funciona como se esperaba



objective-c core-data (2)

Estoy usando UIManagedDocument con el contexto Parent Child.

En el contexto de mi hijo, hago lo siguiente

Código 1

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

El código anterior devuelve los resultados esperados (solo miembros no eliminados para el evento).

Código 2

Pero este código no. Obtiene todos los registros.

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

Parece confuso Ambos deberían devolver los mismos resultados, pero predicateWithBlock devuelve resultados correctos cuando predicateWithFormat devuelve todos los registros.

¿Cuáles son los pros y los contras de usar predicateWithBlock lugar de predicateWithFormat ?


El problema es que ha definido un atributo deleted para su entidad. Eso entra en conflicto con el método isDeleted de NSManagedObject , por lo que debe cambiar el nombre de ese atributo.

El siguiente "experimento" muestra que ocurren cosas extrañas si llama a su atributo "eliminado" ( c es un objeto gestionado con un atributo personalizado 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

Su "Código 1" se refiere a la propiedad, por lo tanto, devuelve el resultado esperado. "Código 2" usa Codificación de valor-clave, y [c valueForKey:@"deleted"] devuelve YES si el objeto realmente ha sido eliminado del contexto.

Por lo tanto, renombrar ese atributo debería resolver su problema. Desafortunadamente, el compilador no emite advertencias si un nombre de atributo entra en conflicto con un método incorporado.


Use el marcador de posición de formato para reemplazar el valor de bool:

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

Su uso de la ruta de la clave probablemente sea correcto, pero el lado derecho probablemente no se vea como "NO" para el analizador.