When using primitive setters (e.g. setPrimitiveValue:forKey:
)to change values of NSManagedObjects
(or their subclasses), will these changes be included in the userInfo of NSManagedObjectContextObjectsDidChange
notifications, or the objects be listed in the updatedObjects of NSManagedObjectContextDidSave
notifications?
Subsequently, will values set by primitives be saved to disk? (assuming use of a sqlite persistent store)
I haven't been able to find any specific information on this, and I'd rather not make assumptions from my limited testing, or at least not without (attempting) a deeper understanding of it. Thanks!
Did some further testing with a small sample project to minimize other factors, and here are my findings:
Saving is dependent on willChangeValue:forKey:
notifications. As long as the NSManagedObject
is KVC compliant for that key, this call will set the object's hasChanges
flag to YES
. When this happens, an object will be included in the next NSManagedObjectContextObjectsDidChange
notification. The NSManagedObject
itself knows exactly which values have changed though, regardless of what keys KVO notifications were posted for.
E.g. even if key A is changed via the primitive setter, and a notification is posted for key B's change, the object will notice the change for key A.
Similarly, NSManagedObjectContextDidSave
will only save an object whose hasChanges
is YES
but again, the object knows of all changed values regardless of the notifications posted, and all changes will be saved to disk.
I was surprised that didChangeValue:forKey:
does not have any effect on saving behaviour. It is key to undo management though, which requires the standard wrapping of KVO calls around the primitive setter to function:
[self willChangeValueForKey:@"key"];
[self setPrimitiveValue:value forKey:@"key"];`
[self didChangeValueForKey:@"key"];