当使用addObserver:forKeyPath:options:context:观察对象上的值时,最终需要调用该对象上的removeObserver:forKeyPath:,以便稍后进行清理.但在这样做之前,是否可以判断一个对象是否真的在观察该属性?

我试图在我的代码中确保一个对象只在需要的时候移除一个观察者,但在某些情况下,观察者可能会try 两次移除自己.我正在努力防止这种情况发生,但以防万一,我只是想弄清楚是否有办法首先判断我的代码是否真的是某个观察者.

推荐答案

[...] 有没有可能判断一个物体是否真的观察到了这一点

不可以.在处理KVO时,您应该始终记住以下模型:

当建立观察时,你有责任删除该精确观察.一个观察结果是通过其上下文来识别的,因此,上下文必须是唯一的.在接收通知时(在Lion中,在移除观察者时),应该始终测试上下文,而不是路径.

处理观察对象的最佳实践是,在观察对象的设定器中移除并建立观察:

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时,您必须确保观察者和被观察者这两个对象在观察到位时都是活动的.

当添加一个观察时,你必须平衡这一点,只删除一个相同的观察.不要以为你是唯一一个使用KVO的人.框架类可能会出于自己的目的使用KVO,所以一定要在回调中判断上下文.

我想指出的最后一个问题是:观察到的属性必须符合KVO.You can't just observe anything

Objective-c相关问答推荐

反编译ARM64和理解分支目标边界

如何限制 UITextField 中的特殊字符(点和下划线除外)?

将 NSArray 保存到 NSUserDefaults 并在 NSMutableArray 中获取它

UIApplication.sharedApplication.delegate.window 和 UIApplication.sharedApplication.keyWindow 有什么区别?

使用 arc4random() 时如何 Select 值的范围

目标 C:在不离开应用程序的情况下发送Electron邮件

如何在 iPhone 应用程序的 UINavigationBar 中添加图像

从 Storyboard 实例化视图控制器与创建新实例

与 iOS 6.0 原生 Facebook 集成共享:通过我的应用名称发布?

使用 NSMutableArray 的二维数组

try 标记应用程序图标但未获得用户标记应用程序的权限:iOS 8 Xcode 6

如何在 iPhone 上显示来自 API 的 HTML 文本?

以编程方式创建 UITableView

在不导入自己的情况下播放系统声音

'supportedInterfaceOrientations' 实现中的返回类型冲突: - 警告

如何禁用 UIButton?

如何在 Objective-C 中创建一个空白的透明 png?

iOS Buttons - 添加边框

iOS 11 large-title导航栏不折叠

@class 在 Objective-C 中做了什么?