删除观察者 iOS
Remove Observer iOS
我想在我的代码中删除这个观察者:
[self.noteLabel addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL];
删除它的最佳做法是什么?
谢谢
编辑
我想移除这个观察者,因为我需要移除它的parentView。实际上它因为这个观察者而崩溃。与观察者一起删除子视图的好做法是什么?感谢您的帮助。
无论什么时候你想移除一个观察者,你只需要使用removeObserver
和正确的参数。
[self.noteLabel removeObserver:self forKeyPath:@"contentSize"];
您提供的内容并不完全安全。您可以使用这样的代码:
#pragma mark - KVO
static void *_myContextPointer = &_myContextPointer;
- (void)enableObserver:(BOOL)enable onObject:(id)object selector:(SEL)selector {
NSString *selectorKeyPath = NSStringFromSelector(selector);
if (enable) {
[object addObserver:self forKeyPath:selectorKeyPath options:0 context:&_myContextPointer];
} else {
@try {
[object removeObserver:self forKeyPath:selectorKeyPath context:&_myContextPointer];
} @catch (NSException *__unused exception) {}
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (context != _myContextPointer) {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
return;
}
[self observerActionForKeyPath:keyPath ofObject:object change:change];
}
并使用这样的代码来处理您的观察者:
- (void)observerActionForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change {
NSString *contentSizeKeyPath = NSStringFromSelector(@selector(contentSize));
if ([keyPath isEqualToString:contentSizeKeyPath]) {
// do something
}
}
那你就叫它吧,例如:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self enableObserver:YES onObject:self selector:@selector(contentSize)];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self enableObserver:NO onObject:self selector:@selector(contentSize)];
}
通过使用这样的代码,您的应用不会因为连续几次删除观察者而崩溃。此外,您不能在 属性 名称中打错字,它会在您重构代码时动态更改。所有 KVO 都在一个地方。
您可以在 NSHipster 页面上阅读有关安全 KVO 的更多信息。
通常您会在 -init
中开始观察一些关键路径,并在 -dealloc
中停止观察。
我会在 -dealloc
中注销自己。
我想在我的代码中删除这个观察者:
[self.noteLabel addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL];
删除它的最佳做法是什么? 谢谢
编辑
我想移除这个观察者,因为我需要移除它的parentView。实际上它因为这个观察者而崩溃。与观察者一起删除子视图的好做法是什么?感谢您的帮助。
无论什么时候你想移除一个观察者,你只需要使用removeObserver
和正确的参数。
[self.noteLabel removeObserver:self forKeyPath:@"contentSize"];
您提供的内容并不完全安全。您可以使用这样的代码:
#pragma mark - KVO
static void *_myContextPointer = &_myContextPointer;
- (void)enableObserver:(BOOL)enable onObject:(id)object selector:(SEL)selector {
NSString *selectorKeyPath = NSStringFromSelector(selector);
if (enable) {
[object addObserver:self forKeyPath:selectorKeyPath options:0 context:&_myContextPointer];
} else {
@try {
[object removeObserver:self forKeyPath:selectorKeyPath context:&_myContextPointer];
} @catch (NSException *__unused exception) {}
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (context != _myContextPointer) {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
return;
}
[self observerActionForKeyPath:keyPath ofObject:object change:change];
}
并使用这样的代码来处理您的观察者:
- (void)observerActionForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change {
NSString *contentSizeKeyPath = NSStringFromSelector(@selector(contentSize));
if ([keyPath isEqualToString:contentSizeKeyPath]) {
// do something
}
}
那你就叫它吧,例如:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self enableObserver:YES onObject:self selector:@selector(contentSize)];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self enableObserver:NO onObject:self selector:@selector(contentSize)];
}
通过使用这样的代码,您的应用不会因为连续几次删除观察者而崩溃。此外,您不能在 属性 名称中打错字,它会在您重构代码时动态更改。所有 KVO 都在一个地方。
您可以在 NSHipster 页面上阅读有关安全 KVO 的更多信息。
通常您会在 -init
中开始观察一些关键路径,并在 -dealloc
中停止观察。
我会在 -dealloc
中注销自己。