[英]iOS KVO - Cannot remove an observer
I have a simple Viewcontroller that is KVO compliant and has the following in it: 我有一个符合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"];
}
the issue im having is that sometimes user are reporting the following error: 我遇到的问题是,有时用户报告以下错误:
Cannot remove an observer <MyViewController 0x145d0c8d0> for the key path "importStuff" from <MyViewController 0x1741b2280> because it is not registered as an observer.
the addObserver call is not called anywhere else in code. addObserver调用不会在代码中的任何其他地方调用。 is it something about the life cycles im missing ? 这是关于生命周期的遗失吗? isn't viewDidAppear guaranteed to be called once (so it should register the keys right ?) 是不是viewDidAppear保证被调用一次(所以它应该正确注册键?)
Apple Docs say there is a way to add observer when view is visible only. Apple Docs说,当视图仅可见时,有一种方法可以添加观察者。 According to Figure 1 - Valid State Transitions you can use pair viewWillAppear
/ viewWillDisppear
for adding and removing observers. 根据图1 - 有效状态转换,您可以使用pair viewWillAppear
/ viewWillDisppear
来添加和删除观察者。 At the same time you can use init
/ dealloc
pair, but not viewDidLoad
/ dealloc
- view can be not loaded, but controller deallocated. 同时你可以使用init
/ dealloc
对,但不能使用viewDidLoad
/ dealloc
- view不能加载,而是取消分配控制器。
Your code should be: 你的代码应该是:
- (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"];
}
There's no guarantee that a viewDidAppear
will be matched with a viewWillDisappear
every time. 无法保证每次都会将viewDidAppear
与viewWillDisappear
匹配。 This means your KVO registration/unregistration would potentially be unbalanced and non-deterministic. 这意味着您的KVO注册/注销可能不平衡且不确定。 You should perform KVO registration/unregistration in guaranteed pairings like viewDidLoad
and dealloc
. 您应该在有保证的配对中执行KVO注册/取消注册,例如viewDidLoad
和dealloc
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.