iOS KVO观察者模式(坑),移除观察者removeObserver崩溃

问题

在ViewDidLoad 中注册监听者 在ViewController 中dealloc 函数中调用removeObserver移除观察者发生崩溃。

代码


#import "BController.h"

@interface BController ()

@property (nonatomic, copy) NSString *name;

@end

@implementation BController

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

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

}

- (void)dealloc{
   [self removeObserver:self forKeyPath:@"name"];
}


@end



#import "AController.h"

@interface AController ()

@property (nonatomic, copy) NSString *name;

@end

@implementation AController

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

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{

}

- (void)dealloc{
   [self removeObserver:self forKeyPath:@"name"];
}

- (void)testA{
     BController *bcontroller = [[BController alloc] init];
      [self.navigationController pushViewController:bcontroller animated:YES];
}

- (void)testB{
     BController *tempController = [[BController alloc] init];
 BController *controller = [[BController alloc] init];
      [self.navigationController pushViewController:controller animated:YES];
}


@end

分析

如果removeObserver 移除观察者失败,一般情况就是没有注册观察者,但是检查代码的时候发现已经在代码中注册了观察者呢???? 这是就要检查是否真正的调用了注册函数。
在AController中 testA 创建了bcontroller 控制器并跳转,显然已经调用了bcontroller中的

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

当从bcontroller返回时调用了,移除了观察者,这是正确的运行正常

- (void)dealloc{
   [self removeObserver:self forKeyPath:@"name"];
}

但是在testB函数中,产生了奔溃

- (void)testB{
     BController *tempController = [[BController alloc] init];
     BController *controller = [[BController alloc] init];
      [self.navigationController pushViewController:controller animated:YES];
}

这是为什么呢?原来是tempController 这个控制器被创建后并没有跳转,也就是没有调用到注册函数

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

但因为,tempController 没有任何东西引用它,意思就是tempController 这个对象创建了并没有什么用处,当执行完testB函数后会被释放并调用dealloc函数,移除观察者

- (void)dealloc{
   [self removeObserver:self forKeyPath:@"name"];
}

没有注册观察观察者,却想要移除观察者,自然产生了崩溃了

你可能感兴趣的:(iOS KVO观察者模式(坑),移除观察者removeObserver崩溃)