Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
728 views
in Technique[技术] by (71.8m points)

cocoa - Observing an NSMutableArray for insertion/removal

A class has a property (and instance var) of type NSMutableArray with synthesized accessors (via @property). If you observe this array using:

[myObj addObserver:self forKeyPath:@"theArray" options:0 context:NULL];

And then insert an object in the array like this:

[myObj.theArray addObject:NSString.string];

An observeValueForKeyPath... notification is not sent. However, the following does send the proper notification:

[[myObj mutableArrayValueForKey:@"theArray"] addObject:NSString.string];

This is because mutableArrayValueForKey returns a proxy object that takes care of notifying observers.

But shouldn't the synthesized accessors automatically return such a proxy object? What's the proper way to work around this--should I write a custom accessor that just invokes [super mutableArrayValueForKey...]?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

But shouldn't the synthesized accessors automatically return such a proxy object?

No.

What's the proper way to work around this--should I write a custom accessor that just invokes [super mutableArrayValueForKey...]?

No. Implement the array accessors. When you call these, KVO will post the appropriate notifications automatically. So all you have to do is:

[myObject insertObject:newObject inTheArrayAtIndex:[myObject countOfTheArray]];

and the Right Thing will happen automatically.

For convenience, you can write an addTheArrayObject: accessor. This accessor would call one of the real array accessors described above:

- (void) addTheArrayObject:(NSObject *) newObject {
    [self insertObject:newObject inTheArrayAtIndex:[self countOfTheArray]];
}

(You can and should fill in the proper class for the objects in the array, in place of NSObject.)

Then, instead of [myObject insertObject:…], you write [myObject addTheArrayObject:newObject].

Sadly, add<Key>Object: and its counterpart remove<Key>Object: are, last I checked, only recognized by KVO for set (as in NSSet) properties, not array properties, so you don't get free KVO notifications with them unless you implement them on top of accessors it does recognize. I filed a bug about this: x-radar://problem/6407437

I have a list of all the accessor selector formats on my blog.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...