当调用insertObject:in <Key> AtIndex:时,是否应通知观察者?

Pau*_*ely 4 cocoa objective-c

我有一个绑定到阵列控制器的模型.我需要能够直接更新模型并向阵列控制器发送有关更新的通知.在我的搜索中,我发现我可以通过mutableArrayValueForKey:在我的模型上使用并通过返回的NSMutableArray进行更新来实现这一点.

我还发现了一些引用让我相信我也可以更新模型并在我实现并使用KVC兼容的getter和可变索引访问器时发送通知.在我的代码中我实现了

-countOf<Key>:
-objectIn<Key>AtIndex:
-insertObject:in<Key>AtIndex:
-removeObjectFrom<Key>AtIndex:
Run Code Online (Sandbox Code Playgroud)

通话insertObject:in<Key>AtIndex:并未导致我的观察员收到通知.下面的代码是我可以想出的最小的部分来测试我想要做的事情.

#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;
}
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时,我得到以下输出:

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

我期待看到另外三条日志消息,说theArray现在有2个,3个或4个项目.我认为调用insertObject:inTheArrayAtIndex应该通知观察者theArray已经改变,但在我的代码中它不是.

我是否认为insertObject:inTheArrayAtIndex应该导致向观察员发送通知theArray?或者,我在实施中遗漏了什么?任何帮助表示赞赏.

Pet*_*sey 9

这是因为你没有实现insert和remove方法.

"你说的话."我也是这样做的!"

不,不完全.几乎,但是你说错了:它是.removeObjectFromTheArrayAtIndex:

应用该修复后,所有六个更改都会导致观察者通知.