I am using UIManagedDocument with Parent Child context.
In my child context I do the following
Code 1
NSSet *results = [self.event.memberships filteredSetUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return ([[evaluatedObject deleted] boolValue] == NO);
}]];
Above code returns the expected results (only Not deleted members for the event).
Code 2
But this code does not. It fetches all records.
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"deleted == NO"];
NSSet *results = [self.event.memberships filteredSetUsingPredicate:predicate];
It seems confusing. Both should return same results, but predicateWithBlock
returns correct results where as predicateWithFormat
returns all records.
What are the pros and cons of using predicateWithBlock
instead of predicateWithFormat
?
Use the formatting placeholder to replace the bool value:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"deleted", @(NO)];
Your use of the key path is probably ok, but the right-hand side probably doesn't look like "NO" to the parser.
The problem is that you have defined an attribute
deleted
for your entity. That conflicts with theisDeleted
method ofNSManagedObject
, so you should rename that attribute.The following "experiment" shows that strange things happen if you call your attribute "deleted" (
c
is a managed object with a customdeleted
attribute):Your "Code 1" refers to the property, therefore it returns the expected result. "Code 2" uses Key-Value Coding, and
[c valueForKey:@"deleted"]
returnsYES
if the object actually has been deleted from the context!So renaming that attribute should solve your problem. Unfortunately the compiler does not emit warnings if an attribute name conflicts with a built-in method.