-primitiveValueForKey: 有什么意义?
-setPrimitiveValue:forKey:
不会触发 KVO 通知。但在我的大脑中,KVO 只有当事情发生变化时才有意义。但是,当我只访问它以进行读取时,如何更改某些内容呢?
-primitiveValueForKey:
仅获取某个键的对象。但它不会修改它。那么为什么在使用 -valueForKey:
时会导致 KVO 通知呢?
(当然有一点,但我还没有看到。)
-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.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
-primitiveValueForKey:
和-setPrimitiveValue:forKey:
方法主要由 Core Data 使用。特别是,核心数据不仅需要知道您何时要修改属性;还需要知道您何时要修改属性。它也需要知道您何时要访问它,以便它可以实现故障排除。因此,Core Data 添加了在 getter 中使用的
-{will,did}AccessValueForKey:
方法,就像在 setter 中使用的-{will,did}ChangeValueForKey:
方法一样作为 KVO 钩子。然而,还有另一个问题:核心数据实际上还为您管理建模属性的底层存储。因此,您需要某种方法来在
-{will,did}{Access,Change}ValueForKey:
方法建立的屏障内操作此底层存储。这就是-primitiveValueForKey:
和-setPrimitiveValue:forKey:
发挥作用的地方。这就是为什么在
存在之前实现核心数据 getter 和 setter 的标准模式@property
和@dynamic
,看起来像这样:当然,现在,如果您希望 Core Data在运行时为您生成这些内容:
但是,在某些情况下,您仍然希望在不 KVO 或故障触发的情况下操作底层存储。因此,Core Data 也提供了一种新的方法来实现这一点,也是围绕属性声明和自动合成构建的:
请注意,我将类延续放在 .m 文件中;它不是 Person 外部的代码(甚至是
-awakeFromInsert
和-awakeFromFetch
之外的代码)应该接触的东西。但它确实让我可以获取“name”属性的底层存储,而无需在代码中嵌入文字字符串,并且可以使用真实类型。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
@property
and@dynamic
, looked like this:Now of course, you can just declare a property and define it as
@dynamic
if 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
-awakeFromInsert
and-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.