我有一个带有NSMutableArray
KVO 观察到的属性的视图控制器:
@interface MyViewController ()
@property (strong, nonatomic) NSMutableArray *values;
@end
@implementation MyViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.values = [NSMutableArray array];
[self addObserver:self forKeyPath:@"self.values" options:0 context:nil];
}
- (void)dealloc
{
[self removeObserver:self forKeyPath:@"self.values"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"self.values"])
{
// The code here is a bit more complex than that, but the main idea
// is to mutate the object
[self.values addObject:[NSDate date]]; // This line triggers a KVO notification, causing an infinite recursion
}
}
@end
我实现的目标是对数组中的每个产品应用折扣,并在每次将产品添加到数组时重新计算这些折扣。
我想在收到通知时修改观察到的属性,但显然上面的代码不起作用,它会进入无限递归。
一种解决方案是在开头删除观察者observeValueForKeyPath...
并在结尾重新添加观察者。
虽然这看起来有点难看,并且可能会导致问题是属性在一个线程上修改而observeValueForKeyPath...
在另一个线程上运行。
编辑:正如 Wain 所指出的,这里真正的问题是我NSMutableArray
self.value
可能包含不可变对象(NSDictionnary
s ),我无法用它们的可变等价物替换它们,例如:
[self.value replaceObjectAtIndex:0 withObject:[self.value[0] mutableCopy]];
不触发 KVO 通知。