问题
在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"];
}
没有注册观察观察者,却想要移除观察者,自然产生了崩溃了