key value observers were still registered with it when controller is deallocated
dealloc, ios, key-value-observing, memory, objective-c
Solution
From my experience best way to add and remove observer in iOS.
Add observer in ViewDidLoad:-
- (void)viewDidLoad {
[super viewDidLoad];
[self addObserver:self forKeyPath:@"dataContainer.report" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}
To observe the observer we have to do this:-
Don't remove observer in observeValueForKeyPath
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
id oldC = [change objectForKey:NSKeyValueChangeOldKey];
id newC = [change objectForKey:NSKeyValueChangeNewKey];
if([keyPath isEqualToString:@"dataContainer.report"]) {
if (oldC != newC) {
[self updateDataContainer];
[self reportView];
}
}
}
Remove Observer In dealloc :
call remove once here
- (void)dealloc {
@try{
[self removeObserver:self forKeyPath:@"dataContainer.report" context:nil];
}@catch(id anException){
}
}
Problem
I added an observer in the code and then removed it in dealloc and viewWillDisappear but still i am getting an error stating *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x167e5980 of class MyController2 was deallocated while key value observers were still registered with it. ``` Current observation info: <NSKeyValueObservationInfo 0x16719f90> ( <NSKeyValueObservance 0x16719fb0: Observer: 0x167e5980, Key path: dataContainer.report, Options: <New: YES, Old: YES, Prior: NO> Context: 0x0, Property: 0x1677df30> )' ``` I created a controller, `MyController` and derive a new controller `MyController2` from it. Now i added KVO in `MyController2`. ``` - (void)viewDidLoad { [super viewDidLoad]; [self addObserver:self forKeyPath:@"dataContainer.report" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; } ``` Then in observeValueForKeyPath :- ``` - (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context { id oldC = [change objectForKey:NSKeyValueChangeOldKey]; id newC = [change objectForKey:NSKeyValueChangeNewKey]; if([keyPath isEqualToString:@"dataContainer.report"]) { if (oldC != newC) { //Remove Observer [self removeObserver:self forKeyPath:@"dataContainer.report" context:nil]; [self updateDataContainer]; [self reportView]; } } } ``` Then i tried to remove observer in viewWillDisappear and dealloc both :- ``` - (void)dealloc { @try{ [self removeObserver:self forKeyPath:@"dataContainer.report" context:nil]; }@catch(id anException){ } } -(void) viewWillDisappear:(BOOL)animated{ @try{ [self removeObserver:self forKeyPath:@"dataContainer.report" context:nil]; }@catch(id anException){ } [super viewWillDisappear:animated]; } ``` I looked at lost of posts , all of them say one thing you need to remove observer. I tried to remove observer from both of them but still i am getting the issue.