I have a simple Viewcontroller that is KVO compliant 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 issue im having is that sometimes user are reporting 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 else in code. is it something about the life cycles im missing ? isn't viewDidAppear guaranteed to be called once (so it should register the keys right ?)
Apple Docs say there is a way to add observer when view is visible only. According to Figure 1 - Valid State Transitions you can use pair viewWillAppear
/viewWillDisppear
for adding and removing observers. At the same time you can use init
/dealloc
pair, but not viewDidLoad
/dealloc
- view can be not loaded, but controller deallocated.
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"];
}
There's no guarantee that a viewDidAppear
will be matched with a viewWillDisappear
every time. This means your KVO registration/unregistration would potentially be unbalanced and non-deterministic. You should perform KVO registration/unregistration in guaranteed pairings like viewDidLoad
and dealloc
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With