iOS拦截系统KVO监听,防止多次删除和添加

本文介绍了在iOS开发中遇到KVO监听器重复添加或删除导致的崩溃问题,并提供了三种解决方案:1) 使用@try @catch处理删除;2) 利用模型数组记录监听状态;3) 通过observationInfo私有属性检查监听状态。
摘要由CSDN通过智能技术生成

最近项目中处理kvo 的时候,遇到一个问题:当我操作的时候,会发现kvo 释放的时候,会崩溃, 崩溃日志如下:

/*Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <SecondViewController 0x7f83d8f30a50> for the key path "kvoState" from <AppDelegate 0x7f83d8c067b0> because it is not registered as an observer.'*/

经过反复研究,发现了错误的原因,并且找到解决错误的办法

下面我将介绍一下我的思路:(慢慢来 跟着我的思路走)

1.我在AppDelegate里面添加一个属性

@property(nonatomic,copy)NSString *kvoState;/* 测试kvo设置的一个字段 */

2.我在我创建的一个ViewController( SecondViewController)里面去监听这个属性

- (void)monitorNet

{

    AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

    // kvo监听属性值的改变

    [appDelegate addObserver:self forKeyPath:@"kvoState" options:NSKeyValueObservingOptionNew context:nil];


}


/**

 *  kvo

 */

- (void)observeValueForKeyPath:(NSString *)keyPath          // 监听的属性名称

                      ofObject:(id)object                   // 被监听的对象

                        change:(NSDictionary *)change       // 属性的值

                       context:(void *)context              // 添加监听时传来的值

{

    AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

    if ([keyPath isEqualToString:@"kvoState"]) {             

        NSNumber *number = [change objectForKey:@"new"];

        NSInteger item = [number integerValue];

        NSLog(@"%@====",appDelegate.kvoState);              

        NSLog(@"%@----",number);

        if ([object isKindOfClass:[AppDelegate class]] ) {

            

        }

    }

    

}

然后我再去释放 复写系统 dealloc 这个方法

-(void)dealloc

{

    AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

    [appDelegate removeObserver:self forKeyPath:@"kvoState"];

}

3.在第二步之后,我点击一个button ,push 到 另外一个ViewController(

TestViewController)里面,然后在TestViewController里面,点击button ,在这个button 的点击事件里面去执行下面的代码:(特地演示错误)

-(void)buttonAction{

    SecondViewController *secondVC = [[SecondViewController alloc]init];/*执行此行代码回报上述的错误*/

    [self.navigationController popViewControllerAnimated:YES];

}


当这个方法执行完之后,就会出现前面所展示的错误
/*Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer <SecondViewController 0x7f83d8f30a50> for the key path "kvoState" from <AppDelegate 0x7f83d8c067b0> because it is not registered as an observer.'*/

为什么会出现这种错误呢????

其实出现这种错误也很简单的:首先在 buttonAction 这个方法内,secondVC 他是一个局部变量,现在是ARC 管理,当这个方法执行完成以后,会销毁 secondVC 这个对象,那么,很自然的就会调用 SecondViewController 里面的 dealloc 这个方法

-(void)dealloc

{

    AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;

    [appDelegate removeObserver:self forKeyPath:@"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值