【发布时间】:2015-07-29 18:25:44
【问题描述】:
我有一个简单的符合 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 保证被调用一次(所以它应该注册键吗?)
【问题讨论】:
-
这不是处理 KVO 的安全方法。如果您的应用被电话打断,则不会调用 viewWillDisappear,但在应用重新启动时可能会再次调用 viewDidAppear。还有许多其他不太理想的可能性。您应该考虑使用更可靠的方法来添加和删除观察者(viewDidLoad、dealloc 等)
-
感谢您的知识。如果我调用 addObserver 两次会发生什么?那么我是否也必须两次删除观察者?这篇文章还说 ViewDidAppear 只被调用一次:stackoverflow.com/questions/11534396/…
-
不回答您的问题,但您可以使用
@try {[self removeObserver:self forKeyPath:@"yourKeyPath"];} @catch (NSException * __unused exception) {}保护自己免受错误的影响 -
@vib 不不不不。不。我是否必须解释这真的是非常非常糟糕的做法?这并不能解决任何问题,只会导致您的程序无法按预期工作并在稍后的某个时间崩溃而没有说明原因。不记录异常也是一个非常糟糕的主意。异常表明出现了问题,您应该注意而不是忽略。
-
不,不能保证 viewDidAppear 每次都会与 viewWillDisappear 匹配。在这些方法中处理 KVO 是非常不好的做法。不要试!在更多记录的配对中执行此操作,例如 viewDidLoad/dealloc