我正在尝试在keypaths上实现一个安全的键值观察。假设我有一个名为person
的数据模型对象,它具有workplace
属性。 workplace
反过来有一个address
属性,我希望观察,所以我通过以下调用设置键值观察:
[person addObserver:theObserver
forKeyPath:@"workplace.address"
options:NSKeyValueObservingOptionNew
context:NULL];
这个工作正常,直到这个人不改变工作场所。一旦发生这种情况:
person.workplace = newWorkplace;
KVC系统正确地崩溃了应用程序,说明“旧的地址被解除分配,而键值观察者仍然注册了它”。 (旧地址是以前工作地址的地址)。
不幸的是,我无法调整'person'类对象的实现,以通知观察者工作场所即将消失。有没有任何模式可以避免这种崩溃?也许可以得到一些其他通知?如果在KVC的情况下遍历关键路径,您是否可以访问此链?
答案 0 :(得分:1)
修改2
在KVO上花了一些时间之后,我发现在你的情况下,你应该观察person.workplace.address
而不是workplace.address
。当您观察person.workplace.address
时,您将获得两件事:
1)由于您拥有person
对象,因此您可以完全控制对象的生命周期。您现在可以在自己选择的时间删除Observer。
2)当workplace
对象被更改时,KVO机制将自动"观察新address
的新workplace
。当然,它会通知您新的address
。
现在,您可以观察address
,而不必担心workplace
在随机时间被替换。这是KVO真正隐藏的力量之一。这允许子类在不知道其生命周期的情况下安全地观察任何超类的对象。
修改1
Best practice to remove an object as observer for some KVO property
此主题中接受的答案最能描述您的情况。您不应该首先观察属性address
,因为您无法控制workplace
的生命周期。你有一个设计问题。
<强>原始强>
您可以在person对象上观察keyPath workplace
。调用此keyPath时,只需删除workplace.address
的.Observer。
[person addObserver:theObserver forKeyPath:@&#34;工作场所&#34; 选项:[NSKeyValueObservingOptionNew] 上下文:NULL];