Reputation: 8871
Given an NSManagedObject subclass with a boolean property deleted (this is demonstrated in two different ways with code below since both approaches are not working):
[Code Listing 1]
@interface MyManagedObject : NSManagedObject
@property (nonatomic, retain) NSNumber *deleted;
// Or @property (nonatomic) BOOL deleted;
@end
created and inserted into Core Data as follows:
[Code Listing 2]
metadata.deleted = [NSNumber numberWithBool:NO];
// metadata.deleted = NO;
and fetched
[Code Listing 3]
// setup entity description
NSEntityDescription* entityDescription = [self entityDescription];
// setup the sorter
NSSortDescriptor* sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"createdAt" ascending:YES];
NSSortDescriptor* sortDescriptorSection = [[NSSortDescriptor alloc] initWithKey:@"myManagedObject.category.title" ascending:YES];
// Build request
NSFetchRequest* request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
[request setSortDescriptors:[NSArray arrayWithObjects:sortDescriptorSection, sortDescriptor, nil]];
[request setPredicate:[NSPredicate predicateWithFormat:@"deleted == %@", [NSNumber numberWithBool:NO]]];
// Fetch request
NSArray* items = [[self managedObjectContext] executeFetchRequest:request error:nil];
returns one item in the items array as expected. The problem is when deleted is modified:
[Code Listing 4]
MyManagedObject* myManagedObject; // Assume initialized
myManagedObject.deleted = [NSNumber numberWithBool:YES];
// myManagedObject.deleted = YES;
// Printing description of myManagedObject in debugger shows deleted = 0 at this point
[myManagedObject.managedObjectContext save:nil];
// Printing description of myManagedObject in debugger still shows deleted = 0 at this point
BOOL testValue = myManagedObject.deleted;
if (testValue) {
NSLog(@"value updated"); // This line is executed
}
Re-executing code listing 3 still yields one item in the items array even after a NSFetchResultsController watching the database has fired an update. If the application is terminated and relaunched, re-executing code listing 3 yields no items in the items NSArray.
Upvotes: 0
Views: 1000
Reputation: 371
Note that this isn't just a problem with deleted and isDeleted. I wrote a database in which I had a "relationship" property, which was an int16 (choice of several relationship types), but then I also had an "isRelationship" boolean which looked at this property and several others to determine whether the content was about the individual or about a relationship. valueForKey:@"relationship" would return the bool for isRelationship - which meant that it also affected NSPredicate. The following predicate:
NSPredicate *pred = [NSPredicate predicateWithFormat:@"relationship IN %@",
@[[NSNumber numberWithShort:Relationship_Dating],
[NSNumber numberWithShort:Relationship_Married]]];
would fail to filter out friend or family relationships because they were all returning 1 from isRelationship instead of the actual relationship value.
Watch out for stupidly "clever" system behavior when "is" booleans are involved.
(I fixed this by changing the "-(bool) isRelationship" method to "-(bool) isRelational".)
Upvotes: 0
Reputation: 539815
Calling a Core Data property "deleted" conflicts with the isDeleted
property of NSManagedObject
.
Compare Core Data NSPredicate "deleted == NO" does not work as expected for a similar problem and some experiments.
Btw. calling a property "updated" causes also problems, compare Cannot use a predicate that compares dates in Magical Record.
Upvotes: 2
Reputation: 4452
You should not be using deleted as a property name for an NSManagedObject subclass.
Also, deleted is an NSNumber, not a BOOL. So, when you are using:
BOOL testValue = myManagedObject.deleted;
if (testValue) {
NSLog(@"value updated"); // This line is executed
}
You are testing if myManagedObject's deleted property is nil or not. If there is a value (even [NSNumber numberWithBool:YES]), testValue will be true.
On an unrelated note, I also advice to capture and log the error when calling NSManagedObjectContext's save method.
Upvotes: 0