Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Cocoa KVO, why doesn't a change on a NSMutableArray proxy notify observers?

I'm implementing a DocumentsManager class in iOS, and I want to make a to-many property called documents to be KVO compliant. It seems to mostly work, and my KVO accessor and mutator methods are called. The thing that bothers me, however, is that any change made directly on the NSMutableArray proxy returned by calling mutableArrayValueForKey: on my instance doesn't notify observers.

So, this code notifies me about the insertion of @"aaa" but not of @"bbb", although they are both actually inserted in visible in docsProxy. Is that expected behavior? If so, what is the advantage of using the mutableArrayValueForKey: method?

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!
like image 526
Jean-Philippe Pellet Avatar asked Nov 12 '13 15:11

Jean-Philippe Pellet


1 Answers

It turns out that mutableArrayValueForKey: does not always return a notifying array. It only does so when observers have already been registered on the observed object!

So swapping my first two lines fixes the problem:

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

Can't help thinking how much time we'd save if we could read the source code of those methods…

like image 156
Jean-Philippe Pellet Avatar answered Oct 04 '22 11:10

Jean-Philippe Pellet