Thom
Thom

Reputation: 2493

Core Data predicate not matching boolean attribute

I have an NSManagedObject subclass with a boolean attribute. It's non-optional, with NO as the default. In the model interface it is declared as @property (nonatomic, retain) NSNumber * deleted;, in the implementation, @dynamic deleted;.

It is persisting correctly if I check the underlying SQLite file. However, I am finding that fetches with predicates querying this attribute do not work correctly. I have tried deleted == YES, deleted == %@ with @YES and [NSNumber numberWithBool:YES], and indeed deleted == 1. I've even tried using a single equals sign out of pure voodoo paranoia. Nothing works.

This is causing a bug in my code using an NSFetchedResultsController. The full predicate is currently (list = %@) OR (deleted = YES). I change deleted to @YES, change the value of list, and the controller issues an unexpected NSFetchedResultsChangeDelete, despite the object still logically matching the predicate.

There's no doubting it doesn't match the predicate however (at least in memory), as I've tested with:

BOOL matchesBefore = [self.fetchedResultsController.fetchRequest.predicate evaluateWithObject:thing];
// do stuff, setting thing.deleted = @YES, thing.list = @"something else"
BOOL matchesAfter = [self.fetchedResultsController.fetchRequest.predicate evaluateWithObject:thing];
NSAssert(matchesBefore && matchesAfter, @"Should still match");

Interestingly, in the debugger, the attribute is displayed as deleted = 0;, however printing the actual NSNumber yields (NSNumber *) $5 = 0x07455ec0 1. Again, in the underlying database, the value is stored correctly as '1'.

So I'm greatly confused. Any ideas? This is iOS, on 5.x both in the simulator and on device.

Upvotes: 0

Views: 799

Answers (1)

ilmiacs
ilmiacs

Reputation: 2576

Sounds like a collision with reserved names, some deep lying undocumented (?) use of the keyword deleted. (Wouldn't be strange in the context of a NSManagedObject, or maybe in NSFetchedResultsController.) Try to change the name of the field to something else.

Upvotes: 5

Related Questions