我有一个观点,就是在init
上观察自己的值:
[self addObserver:self forKeyPath:@"focusPointOfInterestIndicator" options:0 context:kSRCameraViewObserverContext];
[self addObserver:self forKeyPath:@"exposurePointOfInterestIndicator" options:0 context:kSRCameraViewObserverContext];
[self addObserver:self forKeyPath:@"paused" options:0 context:kSRCameraViewObserverContext];
[self addObserver:self forKeyPath:@"previewLayerGravity" options:0 context:kSRCameraViewObserverContext];
在dealloc
上,观察者被移除,因为他们应该是这样的:
[self removeObserver:self forKeyPath:@"focusPointOfInterestIndicator"];
[self removeObserver:self forKeyPath:@"exposurePointOfInterestIndicator"];
[self removeObserver:self forKeyPath:@"paused"];
[self removeObserver:self forKeyPath:@"previewLayerGravity"];
但是除非调用它两次(有或没有上下文,不会改变任何东西),当视图被释放时我崩溃导致仍然观察到该值。 但是我很确定观察者只被添加一次(因为它是在init的对象中)。
我只是想知道为什么它可以被注册两次?或者通过调用它两次,它让对象有效地删除观察者?如果有人有任何线索?
答案 0 :(得分:2)
init
是NSObjet
的主要初始值设定项,这意味着必须在Apple的initWithCoder
/ initWithFrame
实施中调用init像[super init];
所以你的sharedSetup
被调用了两次
编辑(感谢And Ainu):
更具体地说,init
调用UIView
方法的initWithFrame
方法。
答案 1 :(得分:1)
如果每次移除观察者时都使用try catch,那么这是一种很好的做法。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
@try {
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"LocationSelected" object:nil];
} @catch (id anException){
//do nothing, obviously it wasn't attached because an exception was thrown
}
[[NSNotificationCenter defaultCenter] addObserverForName:@"LocationSelected" object:nil queue:[NSOperationQueue mainQueue] usingBlock: ^(NSNotification *not) {
//Someone posted the notification handle it here
}];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
@try {
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"LocationSelected" object:nil];
} @catch (id anException){
//do nothing, obviously it wasn't attached because an exception was thrown
}
}
答案 2 :(得分:0)
您可以做的另一件事是,不是在init
方法中观察,而是在loadView
或awakeFromNib
方法中替换相同的方法。然后它不会再调用两次。