iOS KVO - 无法删除观察者

时间:2015-07-29 18:25:45

标签: ios key-value-observing

我有一个符合KVO标准的简单Viewcontroller,其中包含以下内容:

  - (void) viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];



        [self addObserver:self forKeyPath:@"importStuff" options:0 context:NULL];
        [self addObserver:self forKeyPath:@"importStuffFailed" options:0 context:NULL];
        }

    - (void) viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];

        [self removeObserver:self forKeyPath:@"importStuff"];
        [self removeObserver:self forKeyPath:@"importStuffFailed"];
      }

我遇到的问题是,有时用户报告以下错误:

Cannot remove an observer <MyViewController 0x145d0c8d0> for the key path "importStuff" from <MyViewController 0x1741b2280> because it is not registered as an observer.

在代码中的其他任何地方都不会调用addObserver调用。这是关于生命周期的遗失吗?是不是viewDidAppear保证被调用一次(所以它应该正确注册键?)

2 个答案:

答案 0 :(得分:11)

Apple Docs说当视图仅可见时,有一种方法可以添加观察者。根据图1 - 有效状态转换,您可以使用对viewWillAppear / viewWillDisppear来添加和删除观察者。同时,您可以使用init / dealloc对,但不能使用viewDidLoad / dealloc - 视图无法加载,但控制器已取消分配。

您的代码应为:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self addObserver:self forKeyPath:@"importStuff" options:0 context:NULL];
    [self addObserver:self forKeyPath:@"importStuffFailed" options:0 context:NULL];
}

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];

    [self removeObserver:self forKeyPath:@"importStuff"];
    [self removeObserver:self forKeyPath:@"importStuffFailed"];
}

答案 1 :(得分:3)

无法保证viewDidAppear每次都与viewWillDisappear匹配。这意味着您的KVO注册/注销可能不平衡且不确定。您应该以{{1​​}}和viewDidLoad等有保证的配对方式执行KVO注册/取消注册。