-1

I've been trying to pinpoint the problem but have not been able to do so because it's very hard to reproduce. Here's the error:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x1455c7fa0 of class JASidePanelViewController was deallocated while key value observers were still registered with it. Current observation info: <NSKeyValueObservationInfo 0x170456680> ( <NSKeyValueObservance 0x1702c3720: Observer: 0x1455c7fa0, Key path: state, Options: <New: YES, Old: NO, Prior: NO> Context: 0x0, Property: 0x17024a080> )'

From the error message, I can try to remove observers before an instance is deallocated. Here's the code:

SidePanelViewController.h

#import "JASidePanelController.h"
@interface SidePanelViewController : JASidePanelController
@end

SidePanelViewController.m

...
@implementation SidePanelViewController
...
- (void)viewDidLoad {
    [super viewDidLoad];
    [self addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:nil];
}

- (void)viewDidUnload:(BOOL)animated {
    [self viewDidUnload:animated];
    [self removeObserver:self forKeyPath:@"state"];
}
...
@end

Update: Doing some more research, I've discovered that viewDidUnload is not a reliable way of removing an observer because it's not always called. Thus, there are 2 possible solutions: 1) create the observer in viewDidLoad while pairing its removal in a -(void) dealloc, or 2) create and remove observers in viewDidAppear and viewWillDisappear (as recommended by Gargoyle).

Vee
  • 1,579
  • 1
  • 28
  • 54
  • 2
    Start by looking at the code that adds an observer to the `JASidePanelViewController`. Make sure you have code that removes that observer when appropriate. Update your question with relevant code. – rmaddy Jun 03 '16 at 22:08
  • 1
    Do a global search for addObserver. Generally my method is that I add observers in viewDidAppear and remove them in viewWillDisappear unless you really needt hem running otherwise. – Gargoyle Jun 03 '16 at 22:33
  • Thanks, rmaddy and Gargoyle. After I found the observers, I could see that the prob was using viewDidLoad and viewDidUnload. When dealloc was called, I noticed that viewDidUnload was not and thus, the observer was not removed beforehand. If you guys want to post the formal solution, I will accept and give you credit. – Vee Jun 04 '16 at 03:16

2 Answers2

1

Add your observers in viewDidAppear() and remove them in viewWillDisappear

Gargoyle
  • 7,401
  • 10
  • 55
  • 99
1

Actually, I ended up pairing create and remove observers within viewDidLoad and dealloc instead of viewDidAppear and viewWillDisappear:

@implementation SidePanelViewController

...

- (void)viewDidLoad{
    [super viewDidLoad];
    [self addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:nil];
}

- (void) dealloc{
    [self removeObserver:self forKeyPath:@"state"];
}

...

@end

Apparently, there are various scenarios where viewWillDisappear was not called and thus, when I used viewDidAppear and viewWillDisappear to create/remove observers, I ended getting the following error at various times:

*** Terminating app due to uncaught exception 'NSRangeException', reason: 'Cannot remove an observer for the key path "state" from because it is not registered as an observer.'

Vee
  • 1,579
  • 1
  • 28
  • 54