Should observers be notified when insertObject: in <Key> AtIndex: is called?

I have a model attached to an array controller. I need to be able to directly update the model and send notifications to the array controller about the update. In my search, I found that I can accomplish this using mutableArrayValueForKey: in my model and updating using the returned NSMutableArray.

I also found some links that made me believe that I could also update the model and send notifications if I implemented and used a KVC-compatible getter and a mutable indexed accessor. In my code I implemented

 -countOf<Key>: -objectIn<Key>AtIndex: -insertObject:in<Key>AtIndex: -removeObjectFrom<Key>AtIndex: 

A call to insertObject:in<Key>AtIndex: did not result in notifying my watchers. The code below is the smallest part that I could come up with to verify what I'm trying to do.

 #import <Foundation/Foundation.h> @interface ModelAndObserver : NSObject { NSMutableArray *theArray; } @property(retain)NSMutableArray *theArray; - (NSUInteger)countOfTheArray; - (NSString *)objectInTheArrayAtIndex:(NSUInteger)index; - (void)insertObject:(NSString*) string inTheArrayAtIndex:(NSUInteger)index; - (void)removeObjectInTheArrayAtIndex:(NSUInteger)index; @end @implementation ModelAndObserver @synthesize theArray; - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { NSLog(@"theArray now has %d items", [theArray count]); } - (NSUInteger)countOfTheArray { return [theArray count]; } - (NSString *)objectInTheArrayAtIndex:(NSUInteger)index { return [theArray objectAtIndex:index]; } - (void)insertObject:(NSString*) string inTheArrayAtIndex:(NSUInteger)index { [theArray insertObject:string atIndex:index]; } - (void)removeObjectInTheArrayAtIndex:(NSUInteger)index { [theArray removeObjectAtIndex:index]; } @end int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; ModelAndObserver *mao = [[ModelAndObserver alloc] init]; [mao addObserver:mao forKeyPath:@"theArray" options:0 context:@"arrayChanged"]; // This results in observeValueForKeyPath... begin called. [mao setTheArray:[NSMutableArray array]]; // This results in observeValueForKeyPath... begin called. [[mao mutableArrayValueForKey:@"theArray"] addObject:@"Zero"]; // These do not results in observeValueForKeyPath... // begin called, but theArray is changed. [mao insertObject:@"One" inTheArrayAtIndex:1]; [mao insertObject:@"Two" inTheArrayAtIndex:2]; [mao insertObject:@"Three" inTheArrayAtIndex:3]; // This results in observeValueForKeyPath... begin called. [[mao mutableArrayValueForKey:@"theArray"] addObject:@"Four"]; [mao removeObserver:mao forKeyPath:@"theArray"]; [mao release]; [pool drain]; return 0; } 

When I run this code, I get the following output:

  2011-02-05 17: 38: 47.724 kvcExperiment [39048: a0f] theArray now has 0 items
 2011-02-05 17: 38: 47.726 kvcExperiment [39048: a0f] theArray now has 1 items
 2011-02-05 17: 38: 47.727 kvcExperiment [39048: a0f] theArray now has 5 items

I expected to see three more log messages that say that theArray now has 2, 3, or 4 elements. I thought the call to insertObject:inTheArrayAtIndex was supposed to notify obvserver that theArray had changed, but this is not the case in my code.

Am I confused that insertObject:inTheArrayAtIndex should cause a notification to be sent to theArray observers? Or am I missing something in my implementation? Any help is appreciated.

+4
source share
1 answer

This is because you did not implement the insert and delete method.

"What are you talking about. "I, too!"

No, not at all. Almost, but you were wrong: It removeObject From TheArrayAtIndex:

When applying this fix, all six changes trigger observer notifications.

+9
source

Source: https://habr.com/ru/post/1338590/


All Articles