我在代码中添加了一个观察者,然后在 dealloc 和 viewWillDisappear 中将其删除,但我仍然收到错误信息
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x167e5980 of class MyController2 was deallocated while key value observers were still registered with it.
Current observation info: <NSKeyValueObservationInfo 0x16719f90> ( <NSKeyValueObservance 0x16719fb0: Observer: 0x167e5980, Key path: dataContainer.report, Options: <New: YES, Old: YES, Prior: NO> Context: 0x0, Property: 0x1677df30> )'
我创建了一个 Controller MyController
并从中派生了一个新的 Controller MyController2
。现在我在 MyController2
中添加了 KVO。
- (void)viewDidLoad {
[super viewDidLoad];
[self addObserver:self forKeyPath:@"dataContainer.report" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}
然后在 observeValueForKeyPath 中:-
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
id oldC = [change objectForKey:NSKeyValueChangeOldKey];
id newC = [change objectForKey:NSKeyValueChangeNewKey];
if([keyPath isEqualToString:@"dataContainer.report"]) {
if (oldC != newC) {
//Remove Observer
[self removeObserver:self forKeyPath:@"dataContainer.report" context:nil];
[self updateDataContainer];
[self reportView];
}
}
}
然后我尝试在 viewWillDisappear 和 dealloc 中删除观察者:-
- (void)dealloc {
@try{
[self removeObserver:self forKeyPath:@"dataContainer.report" context:nil];
}@catch(id anException){
}
}
-(void) viewWillDisappear:(BOOL)animated{
@try{
[self removeObserver:self forKeyPath:@"dataContainer.report" context:nil];
}@catch(id anException){
}
[super viewWillDisappear:animated];
}
我看了 lost of posts ,他们都说一件事你需要删除观察者。我试图从他们两个中删除观察者,但我仍然遇到问题。
最佳答案
根据我的经验,在 iOS 中添加和删除观察者的最佳方式。
在ViewDidLoad中添加观察者:-
- (void)viewDidLoad {
[super viewDidLoad];
[self addObserver:self forKeyPath:@"dataContainer.report" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}
要观察观察者,我们必须这样做:-
Don't remove observer in observeValueForKeyPath
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
id oldC = [change objectForKey:NSKeyValueChangeOldKey];
id newC = [change objectForKey:NSKeyValueChangeNewKey];
if([keyPath isEqualToString:@"dataContainer.report"]) {
if (oldC != newC) {
[self updateDataContainer];
[self reportView];
}
}
}
在 dealloc 中删除观察者:
call remove once here
- (void)dealloc {
@try{
[self removeObserver:self forKeyPath:@"dataContainer.report" context:nil];
}@catch(id anException){
}
}
关于ios - 当 Controller 被释放时,键值观察者仍然在其中注册,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37640432/