释放控制器时,关键值观察者仍在其中注册 [英] key value observers were still registered with it when controller is deallocated

查看:121
本文介绍了释放控制器时,关键值观察者仍在其中注册的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在代码中添加了一个观察者,然后在dealloc和viewWillDisappear中将其删除,但仍然出现错误,指出

I added an observer in the code and then removed it in dealloc and viewWillDisappear but still i am getting an error stating

***由于未捕获的异常"NSInternalInconsistencyException"而终止应用程序,原因:实例0x167e5980 类MyController2被释放,而键值观察器被释放 仍在注册.

*** 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>
)'

我创建了一个控制器MyController,并从中派生出一个新的控制器MyController2.现在我在MyController2中添加了KVO.

I created a controller, MyController and derive a new controller MyController2 from it. Now i added KVO in MyController2.

- (void)viewDidLoad {
    [super viewDidLoad];
    [self addObserver:self forKeyPath:@"dataContainer.report" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}

然后在observeValueForKeyPath中:-

Then 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) {
            //Remove Observer

            [self removeObserver:self forKeyPath:@"dataContainer.report" context:nil];
            [self updateDataContainer];
            [self reportView];
        }
    }
}

然后我尝试在viewWillDisappear中删除观察者,并同时释放这两个对象:-

Then i tried to remove observer in viewWillDisappear and dealloc both :-

- (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];
}

我看着丢失的帖子,所有人都说您需要删除观察者的一件事.我试图从他们两个中删除观察者,但仍然遇到问题.

I looked at lost of posts , all of them say one thing you need to remove observer. I tried to remove observer from both of them but still i am getting the issue.

推荐答案

根据我的经验,在Ios中添加和删除观察者的最佳方法.

在ViewDidLoad中添加观察者:-

Add observer in ViewDidLoad:-

- (void)viewDidLoad {
    [super viewDidLoad];
    [self addObserver:self forKeyPath:@"dataContainer.report" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}

要观察观察者,我们必须这样做:-

To observe the observer we have to do this:-

不要在observeValueForKeyPath中删除观察者

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中的观察者:

Remove Observer In dealloc :

致电此处删除一次

call remove once here

- (void)dealloc {
    @try{
        [self removeObserver:self forKeyPath:@"dataContainer.report" context:nil];
    }@catch(id anException){
    }
}

这篇关于释放控制器时,关键值观察者仍在其中注册的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆