哪些类不符合 KVO?
Posted
技术标签:
【中文标题】哪些类不符合 KVO?【英文标题】:Which all are class are not KVO compliant? 【发布时间】:2017-03-19 03:48:25 【问题描述】:以下两段来自 Apple 文档。在一段中,它说所有从 NSObject 继承以使用 KVO 的类都是 KVO 兼容的。在第二段中,它说并非所有类都符合 KVO。有没有不继承NSObject的类?而我知道所有都继承自 NSObject。
最好举个例子,以了解两段之间的区别。
要使用 KVO,首先必须确保观察到的对象, 在这种情况下,帐户符合 KVO。通常,如果您的对象 从 NSObject 继承并且您以通常的方式创建属性,您的 对象及其属性将自动符合 KVO。它 也可以手动实现合规性。 KVO 合规性 描述了自动键值和手动键值之间的区别 观察,以及如何实现两者。
和
重要提示:并非所有类的所有属性都符合 KVO。你 可以按照以下步骤确保您自己的类符合 KVO 标准 KVO 合规性中描述。 Apple 提供的典型属性 只有这样记录的框架才符合 KVO。
【问题讨论】:
除了不继承自NSObject
的对象外,其主要结构如CGSize
【参考方案1】:
要使对象的属性符合 KVO,该对象必须继承 NSObject
,并且该对象还必须:
由于您没有 Apple 框架的源代码,因此您通常无法知道 Apple 提供的类的对象是否符合这些要求,除非查看文档。如果文档说某个属性符合 KVO,那么您就知道它符合要求。否则,您不知道它是否符合要求,因此在物业上使用 KVO 是不安全的。
了解属性有时可能以符合 KVO 的方式更新,而有时以不符合的方式更新,这一点很重要。所以你不能只做一个简单的测试来决定!您的测试可能会显示该属性在您设置属性的方式上符合 KVO,但它不能显示该属性总是以符合 KVO 的方式更新。
例如,每个UIView
都拥有一个CALayer
,并且UIView
的许多属性,包括它的frame
、它的bounds
和它的backgroundColor
实际上是那个@987654328 的属性@。当您在视图上获取或设置属性时,视图的访问器方法只是将消息发送到图层。但是你也可以直接设置图层的属性。所以如果你说view.bounds = someRect
,视图可能会通知 KVO 观察者。但是如果你说view.layer.bounds = someRect
,视图将不会通知 KVO 观察者。但在这两个语句之后,view.bounds
将返回 someRect
。
因此,如果您负责实现该属性,或者该属性被记录为符合 KVO,则您只能依赖该属性符合 KVO。
【讨论】:
【参考方案2】:Key-Value Coding 和 Key-Value Observing 都依赖于命名约定来识别哪些访问器方法对应于哪些属性。
如果您使用声明的属性(使用 @property
关键字)并且不覆盖访问器方法名称,那么访问器方法将符合命名约定,并且 KVC 和 KVO 将能够识别与关键。如果您覆盖方法名称或使用非正式属性,则您有责任遵守命名约定。 (一个常见的情况是使用 getter=is<Key>
作为布尔属性。它是一个被覆盖的 getter 名称,但它仍然符合命名约定。)
除了使用具有常规名称的访问器方法外,类还必须实际使用访问器来修改自己的属性,以便利用自动更改通知。该类不应直接修改其实例变量(在 init 方法或 -dealloc
之外),或者如果这样做,则需要对该属性使用手动更改通知。
你引用的第一句话是说你从NSObject
获得了很多自动行为,假设你遵循命名约定并通过它们的访问器而不是实例变量来修改你的属性。这就是“以通常的方式创建属性”的意思。
第二句话的意思是,您不能假设 Apple 自己的类可以做到这一点。在某些情况下,由于历史实现细节和一般的灵活性,他们保留使其类的属性不兼容的权利。您不得假设这些属性是符合 KVO 的,除非它们被明确记录为符合。
【讨论】:
以上是关于哪些类不符合 KVO?的主要内容,如果未能解决你的问题,请参考以下文章