IOS KVO - Unable to delete observer

I have a simple Viewcontroller that meets the requirements of KVO and has the following in it:

- (void) viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self addObserver:self forKeyPath:@"importStuff" options:0 context:NULL]; [self addObserver:self forKeyPath:@"importStuffFailed" options:0 context:NULL]; } - (void) viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self removeObserver:self forKeyPath:@"importStuff"]; [self removeObserver:self forKeyPath:@"importStuffFailed"]; } 

The problem with im is that sometimes the user reports the following error:

 Cannot remove an observer <MyViewController 0x145d0c8d0> for the key path "importStuff" from <MyViewController 0x1741b2280> because it is not registered as an observer. 

the addObserver call is not called anywhere in the code. Is it something about the life cycles that they lack? is not viewDidAppear is guaranteed to be called once (so that it registers the keys correctly?)

+5
source share
2 answers

There is no guarantee that viewDidAppear will match viewWillDisappear each time. This means that your KVO registration / registration will potentially be unbalanced and non-deterministic. You must complete KVO registration / registration in guaranteed pairings such as viewDidLoad and dealloc .

+4
source

Apple Docs say there is a way to add an observer when the view is visible only. As viewWillAppear in Figure 1 - Valid State Transitions, you can use the viewWillAppear / viewWillDisppear to add and remove observers. At the same time, you can use the init / dealloc pair, but not viewDidLoad / dealloc - the view may not be loaded, but the controller is freed.

Your code should be:

 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self addObserver:self forKeyPath:@"importStuff" options:0 context:NULL]; [self addObserver:self forKeyPath:@"importStuffFailed" options:0 context:NULL]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self removeObserver:self forKeyPath:@"importStuff"]; [self removeObserver:self forKeyPath:@"importStuffFailed"]; } 
+7
source

All Articles