【问题标题】:Should observers be notified when insertObject:in<Key>AtIndex: is called?调用 insertObject:in<Key>AtIndex: 时是否应该通知观察者?
【发布时间】:2011-02-05 22:58:51
【问题描述】:

我有一个与阵列控制器绑定的模型。我需要能够直接更新模型并将有关更新的通知发送到阵列控制器。在我的搜索中,我发现我可以通过在我的模型上使用 mutableArrayValueForKey: 并通过返回的 NSMutableArray 进行更新来完成此操作。

我还发现了一些参考资料,这些参考资料让我相信,如果我实现并使用了符合 KVC 的 getter 和可变索引访问器,我也可以更新模型并发送通知。在我的代码中我实现了

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

致电insertObject:in&lt;Key&gt;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;
}

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

2011-02-05 17:38:47.724 kvcExperiment[39048:a0f] theArray 现在有 0 个项目 2011-02-05 17:38:47.726 kvcExperiment[39048:a0f] theArray 现在有 1 个项目 2011-02-05 17:38:47.727 kvcExperiment[39048:a0f] theArray 现在有 5 个项目

我期待看到另外三条日志消息说 theArray 现在有 2、3 或 4 个项目。我认为调用 insertObject:inTheArrayAtIndex 应该通知观察服务器 theArray 已更改,但在我的代码中没有。

我认为insertObject:inTheArrayAtIndex 应该导致向theArray 的观察者发送通知时感到困惑吗?或者,我在实施过程中遗漏了什么?任何帮助表示赞赏。

【问题讨论】:

    标签: objective-c cocoa


    【解决方案1】:

    这是因为你没有同时实现 insert 和 remove 方法。

    “什么!”,你说。 “我也是!”

    不,不完全是。差不多,但你有一个词错了:是removeObjectFromTheArrayAtIndex:

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

    【讨论】:

      猜你喜欢
      • 2012-11-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-02
      • 2019-09-18
      相关资源
      最近更新 更多