KVO - 如何检查对象是否是观察者? [英] KVO - How to check if an object is an observer?

查看:81
本文介绍了KVO - 如何检查对象是否是观察者?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 addObserver:forKeyPath:options:context:观察对象上的值时,最终你需要调用 removeObserver:forKeyPath: 在该对象上稍后清理。在这之前,是否可以检查一个对象是否实际上正在观察该属性?

When observing a value on an object using addObserver:forKeyPath:options:context:, eventually you'll want to call removeObserver:forKeyPath: on that object to clean up later. Before doing that though, is it possible to check if an object actually is observing that property?

我试图在我的代码中确保一个对象只有一个观察者在需要时被移除,但在某些情况下,观察者可能会尝试将自己移除两次。我正在努力防止这种情况,但为了以防万一,我一直试图弄清楚是否有办法检查我的代码是否实际上是某个东西的观察者。

I've tried to ensure in my code that an object is only having an observer removed when it needs to be, but there are some cases where it's possible that the observer may try to remove itself twice. I'm working to prevent this, but just in case, I've just been trying to figure out if there's a way to check first if my code actually is an observer of something.

推荐答案


[...]是否可以检查对象是否实际观察到
属性?

[...] is it possible to check if an object actually is observing that property?

没有。在处理KVO时,您应始终牢记以下模型:

No. When dealing with KVO you should always have the following model in mind:

建立观察时,您有责任删除该确切观察。观察是通过其背景来确定的 - 因此,背景必须是独特的。当接收通知时(在Lion中,当移除观察者时),你应该总是测试上下文,而不是路径。

When establishing an observation you are responsible for removing that exact observation. An observation is identified by its context—therefore, the context has to be unique. When receiving notifications (and, in Lion, when removing the observer) you should always test for the context, not the path.

处理观察对象的最佳做法是,删除并在观察对象的setter中建立观察结果:

The best practice for handling observed objects is, to remove and establish the observation in the setter of the observed object:

static int fooObservanceContext;

- (void)setFoo:(Foo *)foo
{
    [_foo removeObserver:self forKeyPath:@"bar" context:&fooObservanceContext];

    _foo = foo; // or whatever ownership handling is needed.

    [foo addObserver:self forKeyPath:@"bar" options:0 context:&fooObservanceContext];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if (context == &fooObservanceContext) {
        // handle change
    } else {
        // not my observer callback
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

- (void)dealloc
{
    self.foo = nil; // removes observer
}

使用KVO时,你必须确保两个对象,只要观察到位,观察者和观察者就会活着。

When using KVO you have to make sure that both objects, observer and observee, are alive as long as the observation is in place.

添加观察时,你必须平衡这一点,同时只删除一次观察。不要假设,你是唯一一个使用KVO的人。框架类可能出于自己的目的使用KVO,因此请始终检查回调中的上下文。

When adding an observation you have to balance this with exactly one removal of the same observation. Don't assume, you're the only one using KVO. Framework classes might use KVO for their own purposes, so always check for the context in the callback.

我想指出的最后一个问题:观察到的属性有符合KVO标准。 您不能只观察任何事情

One final issue I'd like to point out: The observed property has to be KVO compliant. You can't just observe anything.

这篇关于KVO - 如何检查对象是否是观察者?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆