简体   繁体   English

密钥路径的安全密钥值观察

[英]Safe Key Value Observing of keypaths

I am trying to implement a safe key value observing on keypaths. 我正在尝试实现对键路径进行观察的安全键值。 Let's suppose that I have a data model object named person that have a workplace property. 假设我有一个名为person的数据模型对象,该对象具有一个workplace属性。 The workplace in turn have a address property that I wish to observe so I set up key value observing with the following call: 反过来, workplace具有我希望观察的address属性,因此我通过以下调用设置了要观察的键值:

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

This works fine until the person does not change workplace. 直到此人不更换工作场所,此方法才能正常工作。 As soon as this happens: 一旦发生这种情况:

person.workplace = newWorkplace;

the KVC system crashes the application correctly saying that "oldAddress was deallocated while key value observers were still registered with it". KVC系统正确地崩溃了该应用程序,并说“ oldAddress已被释放,而键值观察者仍在其中注册”。 (being oldAddress the address of the previous workplace). (为oldAddress以前工作场所的地址)。

Unfortunately I can not tweak the implementation of the class of 'person' object to notify the observer that workplace is going to go away. 不幸的是,我无法调整“人”对象类的实现,以通知观察者工作场所将要消失。 Are there any pattern to avoid this kind of crash? 是否有任何模式可以避免此类崩溃? Maybe one can get some other notifications? 也许可以收到其他通知? How is the keypath being traversed in the case of KVC and do you have access to this chain? 在KVC中如何遍历密钥路径,您是否可以访问此链?

Edit 2 编辑2

After spending some more time with KVO, I found that in your case, you should be observing person.workplace.address instead of workplace.address . 花一些时间与志愿后,我发现,你的情况,你应该观察person.workplace.address而不是workplace.address When you observe person.workplace.address , you achieve 2 things: 当您观察person.workplace.address ,您会实现两件事:

1) Since you owned the person object, you have absolute control over your object's life cycle. 1)由于您拥有person对象,因此您可以完全控制对象的生命周期。 You can now removeObserver at a time of your own choosing. 现在,您可以在自己的时间选择removeObserver。

2) When workplace object is changed, the KVO mechanism will "automagically" observe the new address of the new workplace . 2)更改workplace对象时,KVO机制将“自动”观察新workplace的新address Of course, it will notify you of the new address . 当然,它将通知您新address

Now, you can observe the address without fearing workplace being replaced at random time. 现在,您可以观察address而不必担心会随机更换workplace This is one of the true hidden power of KVO. 这是KVO真正的隐藏力量之一。 This allow subclasses to safely observe any superclass's objects without knowing about their life-cycles. 这样子类就可以安全地观察任何超类的对象,而无需知道它们的生命周期。

Edit 1 编辑1

Best practice to remove an object as observer for some KVO property 删除对象作为某些KVO属性的观察者的最佳实践

The accepted answer in this thread best described your situation. 该线程中可接受的答案最能描述您的情况。 You should not have observe the property address in the first place, since you have no control over the life-cycle of workplace . 首先,您不应该查看物业address ,因为您无法控制workplace的生命周期。 You have a design issue. 您有一个设计问题。

Original 原版的

You can observe the keyPath workplace on the person object. 您可以在person对象上观察keyPath workplace When this keyPath is invoked, you simply removeObserver for workplace.address . 当此的keyPath被调用时,您只需removeObserver的workplace.address

[person addObserver:theObserver forKeyPath:@"workplace" options:[NSKeyValueObservingOptionNew] context:NULL]; [person addObserver:theObserver for KeyPath:@“ workplace”选项:[NSKeyValueObservingOptionNew]上下文:NULL];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM