开发者

Cocoa - KVO and automatic notification for indexed properties [duplicate]

This question already has an answer here: In Cocoa KVO, why doesn't a change on a NSMutableArray proxy notify observers? (1 answer) Closed 9 years ago.

If I have read the documentation correctly, an object can register as an observer for an indexed property (also called a to-many relationship) the same way it can register as an observer of a normal, scalar property.

I have implemented the indexed accessors, and I know they work because an array controller uses them to populate a table view, and a mutable proxy array sees them and uses them, too. Their prototypes are the following:

// Make indexable accessors for data:
- (NSUInteger)countOfData;
- (id)objectInDataAtIndex:(NSUInteger)index;
- (NSArray *)dataAtIndexes:(NSIndexSet *)indexes;
- (void)insertObject:(NSDictionary *)dict inDataAtIndex:(NSUInteger)index;
- (void)insertData:(NSArray *)dataArray atIndexes:(NSIndexSet *)indexes;
- (void)removeObjectFromDataAtIndex:(NSUInteger)index;
- (void)removeDataAtIndexes:(NSIndexSet *)indexes;

I have registered the NSDocument to listen in the following way:

[self addObserver:self 
       forKeyPath:@"data" 
          options:(NSKeyValueObservingOptionNew |
                   NSKeyValueObservingOptionOld |
                   NSKeyValueObservingOptionInitial |
                   NSKeyValueObservingOptionPrior)
          context:dataArrayChange];

I have actually never seen a concrete example in the docs for this, but on the page below (towards the bottom) there is an example of how to do it manually:

http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/KeyValueObserving/Articles/KVOCompliance.html#//apple_ref/doc/uid/20002178-SW3

So my question is: Is there a way to get the notifications automatically, or do I have to do it manually, like the example in the docs?

Edit to add:

First, a bit of context - this is for a very simple NSDocument-based app, in which NSDocument holds the data indexed property (where each object is a dictionary), an array controller is bound to the data property, and a table view displays the data. The reason I want notifications is that I want to implement undo, and when the notifications work, it all works nicely.

Second, the problem arises when I access the data through a proxy created with the call: dataProxy = [[self mutableArrayValueForKey:@"data"] retain]; in the -init method.

The call I have used on the proxy is:

[dataProxy addObject: <an object>]

This calls the accessor insertData:atIndexes: as e开发者_如何转开发xpected but does not generate a notification.

If I call it directly, like this:

[self insertData: <an object> atIndexes: [NSIndexSet indexSetWithIndex:[data count]]];

it works as expected and generates an automatic notification.

Notice that both methods above call the same accessor, and there may still be some subtle detail that is escaping me.

Last, for completeness, the array controller calls the accessors and notifications are generated.


You don't need to worry about manually managing observations, if you have indexed accessors then KVO notifications will be posted automatically.

Have you implemented observeValueForKeyPath:ofObject:change:context: in order to be notified of changes in your observed property? That is the method that will be called when the property changes.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜