我的AppDelegate中有一个名为blocks的NSMutableArray属性。 每当一个对象被添加到这个数组时我想观察。 我读过其他帖子,但我不明白为什么这不起作用。
在我的app委托类中,我实现了
- (void)insertObject:(id)obj inBlocksAtIndex:(NSInteger)index
{
[blocks insertObject:obj atIndex:index];
}
在我的视图控制器的init方法中,我向AppDelegate引用添加了一个观察者。
boardModel = [[UIApplication sharedApplication] delegate];
[boardModel addObserver:self forKeyPath:@"blocks" options:0 context:NULL];
在我的视图控制器的viewDidLoad方法中,我尝试调用我之前实现的KVO索引数组访问器,
[boardModel insertObject:[[Block alloc] init] inBlocksAtIndex:0];
然后我实现了observeValueForKeyPath方法:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"blocks"])
{
NSLog(@"ADDED");
}
}
我已经尝试在observeValueForKeyPath中的if语句之前添加一个NSLog语句,似乎它永远不会被调用。
我也尝试了NSLogging [[boardModel blocks] count],它说计数为1(正在添加对象)。
我一定错过了什么。
答案 0 :(得分:12)
问题是NSArray
不尊重KVO,因此观察密钥路径计数将不起作用。
如果这是MacOSX,请使用NSArrayController
。否则为数组创建一个包装类,在添加/删除数组内容时触发KVO调用,并传递所有其他调用。
答案 1 :(得分:1)
你试过吗
- (void)insertObject:(id)obj inBlocksAtIndex:(NSInteger)index
{
[[self mutableArrayValueForKey:@"blocks"] insertObject:obj atIndex:index];
}
答案 2 :(得分:0)
您正在观察应用委托的blocks
属性,而不是blocks
数组本身。希望以下示例能够明确区分:
// This will fire KVO as you're changing the app delegate's `blocks` property.
appDelegate.blocks = [NSMutableArray array];
// This will not fire KVO as the app delegate's `blocks` property still points
// to the same object; from the app delegate's perspective, nothing's happened.
[appDelegate.blocks addObject:@"Object"];
如果您希望在blocks
数组的内容发生更改时收到通知,请观察数组本身的属性 - 类似count
。更新您的代码:
[boardModel.blocks addObserver:self forKeyPath:@"count" options:0 context:NULL];
答案 3 :(得分:0)
我只是开源了一个非常小的Objective-C库,它为NSMutableArray添加了一个委托。它可能会帮助您实现您想要做的事情。查看FCMutableArray on GitHub
答案 4 :(得分:0)
并非NSMutableArray在某些方面不符合KVO标准,所有符合KVO标准的属性必须是NSObjects。 "计数"是一个NSUInteger;你不能直接观察那个属性。如果它是NSNumber对象,你可以。
来自NSArray头文件:
@interface NSArray<__covariant ObjectType> : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
@property (readonly) NSUInteger count;
顺便问一下,为什么接受答案?很明显,回答者没有测试他的答案。