我有一个绑定到阵列控制器的模型。我需要能够直接更新模型并向阵列控制器发送有关更新的通知。在我的搜索中,我发现我可以通过在模型上使用mutableArrayValueForKey:
并通过返回的NSMutableArray进行更新来实现此目的。
我还发现了一些引用让我相信我还可以更新模型并在我实现并使用KVC兼容的getter和可变索引访问器时发送通知。在我的代码中,我实现了
-countOf<Key>:
-objectIn<Key>AtIndex:
-insertObject:in<Key>AtIndex:
-removeObjectFrom<Key>AtIndex:
调用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;
}
当我运行此代码时,我得到以下输出:
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
的观察者发送通知?或者,我在实施中遗漏了什么?任何帮助表示赞赏。
答案 0 :(得分:9)
这是因为你没有实现insert和remove方法。
“什么!”,你说。 “我也是这样做的!”
不,不完全。差不多,但是你说错了:它是removeObject
From
TheArrayAtIndex:
。
应用该修复后,所有六项更改都会导致观察者通知。