Reputation: 305
I want to remove this observer in my code :
[self.noteLabel addObserver:self forKeyPath:@"contentSize" options:(NSKeyValueObservingOptionNew) context:NULL];
What is the good practice to remove it ? Thanks
EDIT
I want to remove this observer because I need to remove its parentView. Actually it crashes because of this observer. What would be the good practice to remove a subview with an observer ? Thanks for your help.
Upvotes: 0
Views: 746
Reputation: 10776
Typically you start observing some key path in -init
and stop doing so in -dealloc
.
I would unregister yourself in -dealloc
.
Upvotes: 0
Reputation: 12948
This is not completely safe what you've presented. You can use such code:
#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];
}
and ofc such code to handle your observer:
- (void)observerActionForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change {
NSString *contentSizeKeyPath = NSStringFromSelector(@selector(contentSize));
if ([keyPath isEqualToString:contentSizeKeyPath]) {
// do something
}
}
Then you just call it eg:
- (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)];
}
Via using such code, your app won't crash because you remove observers few times in a row. Also you can't make a typo in your property name and it will dynamically change when you refactor your code. All KVO is in one place.
You can read more about safe KVO on NSHipster page.
Upvotes: 0
Reputation: 3590
Whenever you want to remove an observer, you just have to use removeObserver
with the right parameters.
[self.noteLabel removeObserver:self forKeyPath:@"contentSize"];
Upvotes: 1