-setPrimitiveValue:forKey: won’t trigger KVO notifications. But in my brain, KVO only makes sense when something changes. But how can change something when I only access it for read?
-primitiveValueForKey: only gets the object for some key. But it won’t modify it. So why would/could this cause KVO notifications when using -valueForKey:?
(Of course there is a point, but I don’t see it yet.)
The
-primitiveValueForKey:and-setPrimitiveValue:forKey:methods are primarily used by Core Data. In particular, Core Data doesn’t just need to know when you’re going to modify an attribute; it needs to know when you’re going to access it as well, so it can implement faulting.Thus Core Data adds
-{will,did}AccessValueForKey:methods to use in getters, just as-{will,did}ChangeValueForKey:methods exist for use in setters to act as KVO hooks.However, there’s another wrinkle: Core Data actually manages the underlying storage of modeled properties for you as well. So you need some way to manipulate this underlying storage within the barriers established by the
-{will,did}{Access,Change}ValueForKey:methods. That’s where-primitiveValueForKey:and-setPrimitiveValue:forKey:come in.This is why the standard pattern for implementing Core Data getters and setters, prior to the existence of
@propertyand@dynamic, looked like this:Now of course, you can just declare a property and define it as
@dynamicif you want Core Data to generate this stuff for you at runtime:There are some situations though where you still want to manipulate the underlying storage without KVO or fault-firing, however. Thus Core Data provides a new way to get at this as well, also built around property declarations and automatic synthesis:
Note that I put the class continuation in the .m file; it’s not something that code outside Person (or even really code outside
-awakeFromInsertand-awakeFromFetch) should touch. But it does let me get at the underlying storage for the “name” property without embedding literal strings in my code, and with the use of the real types.