键路径的安全键值观察

Safe Key Value Observing of keypaths

我正在尝试实现在键路径上观察的安全键值。假设我有一个名为 person 的数据模型对象,它有一个 workplace 属性。 workplace 依次有一个 address 属性 我希望观察,所以我通过以下调用设置键值观察:

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

在该人不更换工作场所之前,此方法效果很好。一旦发生这种情况:

person.workplace = newWorkplace;

KVC 系统正确地使应用程序崩溃说 "oldAddress was deallocated while key value observers were still registered with it"。 (是oldAddress以前工作单位的地址)。

不幸的是,我无法调整 'person' 对象的 class 的实现来通知观察者工作场所即将消失。有没有什么模式可以避免这种崩溃?也许可以得到一些其他的通知?在 KVC 的情况下,键路径是如何被遍历的?你可以访问这个链吗?

编辑 2

在花了更多时间使用 KVO 之后,我发现在你的情况下,你应该观察 person.workplace.address 而不是 workplace.address。当您观察到 person.workplace.address 时,您实现了两件事:

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

2) 当workplace对象改变时,KVO机制会"automagically"观察新workplace的新address。当然,它会通知你新的 address.

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

编辑 1

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

此线程中接受的答案最能描述您的情况。您一开始就不应该观察 属性 address,因为您无法控制 workplace 的生命周期。你有一个设计问题。

原创

您可以观察人物对象上的 keyPath workplace。调用此 keyPath 时,您只需为 workplace.address.

移除观察者

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