在Cocoa KVO中,为什么NSMutableArray代理上的更改不会通知观察者?

Jea*_*let 6 macos cocoa objective-c key-value-observing ios

我正在DocumentsManageriOS中实现一个类,我想创建一个被称为documentsKVO兼容的to-many属性.它似乎主要工作,我的KVO访问器和mutator方法被调用.然而,困扰我的是,NSMutableArray通过调用mutableArrayValueForKey:我的实例直接在代理上进行的任何更改都不会通知观察者.

因此,这段代码通知我插入@"aaa"但不插入@"bbb",尽管它们实际上都是插入可见的docsProxy.这是预期的行为吗?如果是这样,使用该mutableArrayValueForKey:方法有什么好处?

NSMutableArray *docsProxy = [[DocumentsManager instance] mutableArrayValueForKey:@"documents"];
[[DocumentsManager instance] addObserver:self forKeyPath:@"documents" options:NSKeyValueObservingOptionNew context:NULL];

[[DocumentsManager instance] insertObject:@"aaa" inDocumentsAtIndex:0]; // OK
[docsProxy insertObject:@"bbb" atIndex:0];                              // no notification!
Run Code Online (Sandbox Code Playgroud)

Jea*_*let 5

事实证明,mutableArrayValueForKey:并不总是返回通知数组.只有当观察者已经在观察对象上注册时才会这样做!

所以交换我的前两行修复了这个问题:

[[DocumentsManager instance] addObserver:self forKeyPath:@"documents" options:NSKeyValueObservingOptionNew context:NULL];
NSMutableArray *docsProxy = [[DocumentsManager instance] mutableArrayValueForKey:@"documents"];
Run Code Online (Sandbox Code Playgroud)

如果我们能够阅读这些方法的源代码,不禁想到我们节省了多少时间......

  • 然而,我们有效地做了,回想起来,为什么这是真的应该是显而易见的.KVO创建了一个神奇的子类并实现了一个isa-swizzle(这是记录的).因此,如果您已经创建了代理,那么在混合之后就无法更新代理.https://developer.apple.com/library/ios/documentation/cocoa/conceptual/KeyValueObserving/Articles/KVOImplementation.html (2认同)