2016-07-22 63 views
0

我正试图在keypaths上实现安全的key值观察。假设我有一个名为person的数据模型对象,它具有workplace属性。反过来workplace有一个address属性,我希望看到,所以我设置键值通过以下调用观察:安全密钥值观察keypaths

[person addObserver:theObserver 
     forKeyPath:@"workplace.address" 
      options:NSKeyValueObservingOptionNew 
      context:NULL]; 

这工作得很好,直到该人不改变工作环境。一旦发生这种情况:

person.workplace = newWorkplace; 

的KVC系统崩溃正确地说,“oldAddress被释放,而键值观察家仍用它注册”的申请。 (旧地址是以前工作地点的地址)。

不幸的是,我不能调整'人'对象类的实现来通知观察者,工作场所将要消失。有没有什么模式可以避免这种崩溃?也许可以得到一些其他的通知?在KVC的情况下如何遍历keypath,并且您是否有权访问此链?

回答

1

编辑2

花更多的时间与志愿后,我发现,你的情况,你应该观察person.workplace.address,而不是workplace.address。当你观察到person.workplace.address时,你实现了两件事:

1)由于你拥有person对象,你可以绝对控制你的对象的生命周期。您现在可以在您自己选择的时间移除Observer。

2)当workplace对象改变时,KVO机制将“自动”观察新的workplace的新address。当然,它会通知您新的address

现在,您可以观察address而不用担心workplace在随机时间被替换。这是KVO真正隐藏的力量之一。这允许子类在不知道其生命周期的情况下安全地观察任何超类的对象。

编辑1

Best practice to remove an object as observer for some KVO property

在这个线程接受的答案最好的描述你的情况。您不应该首先观察address,因为您无法控制workplace的生命周期。你有一个设计问题。

原始

您可以在人员对象上观察的keyPath workplace。当调用这个keyPath时,你只需删除Observer为workplace.address

[人的addObserver:观察家报 forKeyPath:@ “职场” 选项:[NSKeyValueObservingOptionNew] 方面:NULL];