Apple docs的两个不同段落。在一个段落中,它表示所有继承自NSObject以使用KVO的类都符合KVO。在第二段中,它表示并非所有类都符合KVO标准。那些不符合KVO标准的课程是哪些?是否有任何类不继承 NSObject ?虽然我知道所有都来自 NSObject 。
举一个例子来理解两段之间的区别是理想的。
要使用KVO,首先必须确保观察到的物体, 在这种情况下,帐户符合KVO标准。通常,如果您的对象 继承自NSObject,你以通常的方式创建属性,你的 对象及其属性将自动符合KVO标准。它 也可以手动实现合规性。 KVO合规性 描述了自动键值和手动键值之间的区别 观察,以及如何实现两者。
和
重要提示:并非所有类都符合KVO标准。您 通过以下步骤,可以确保您自己的课程符合KVO 在KVO合规性中描述。通常是Apple提供的属性 框架只有KVO兼容,如果它们被记录下来的那样。
答案 0 :(得分:1)
对于符合KVO的对象的属性,该对象必须继承NSObject
,并且该对象也必须:
由于您没有Apple框架的源代码,因此除了检查文档外,您通常无法知道Apple提供的类的对象是否符合这些要求中的任何一个。如果文档说某个属性符合KVO标准,那么您就知道它符合要求。否则,您不知道它是否符合要求,因此在酒店使用KVO是不安全的。
了解某个属性有时可能会以符合KVO标准的方式更新,而其他时候以不合规的方式更新,这一点非常重要。所以你不能做一个简单的测试来决定!您的测试可能会显示该属性与您设置属性的方式符合KVO,但它无法显示该属性始终以KVO投诉方式更新。
例如,每个UIView
拥有一个CALayer
,以及许多UIView
的属性,包括其frame
,bounds
,其backgroundColor
实际上是CALayer
的属性。当您在视图上获取或设置属性时,视图的访问器方法只是将消息发送到该层。但您也可以直接设置图层的属性。因此,如果您说view.bounds = someRect
,该视图可能会通知KVO观察员。但是,如果您说view.layer.bounds = someRect
,视图将不通知KVO观察员。但在这些陈述之后,view.bounds
将返回someRect
。
因此,如果您负责该属性的实施,或者该属性被记录为符合KVO,则您只能依赖属性符合KVO。
答案 1 :(得分:0)
键值编码和键值观察都依赖于命名约定来识别哪些访问器方法对应于哪些属性。
如果您使用声明的属性(使用@property
关键字)而您没有覆盖访问者方法名称,那么访问者方法将符合命名约定,KVC和KVO将能够识别方法与钥匙相关联。如果覆盖方法名称或使用非正式属性,则您有责任遵守命名约定。 (一个常见的情况是使用getter=is<Key>
作为布尔属性。它是一个重写的getter名称,但它仍然符合命名约定。)
除了使用具有常规名称的访问器方法之外,类还必须实际使用访问器来修改其自己的属性,以便利用自动更改通知。该类不应直接修改其实例变量(在init方法之外或-dealloc
),如果是,则需要对该属性使用手动更改通知。
你引用的第一句话是说你从NSObject
获得了很多自动行为,假设你遵循命名约定并通过其访问器而不是实例变量修改你的属性。这就是“以通常的方式创造属性”的目标。
第二句话的内容是你不能假设Apple自己的课程那样做。在某些情况下,由于历史实施细节以及一般的灵活性,他们保留使其类别属性不合规的权利。您不能假设属性符合KVO,除非明确说明这些属性。