I have a view (we'll call this view A) that has a weak
property to its superview (view B). View A KVO's its superview, view B. Since view A's reference to view B is a weak property (to prevent a retain cycle), how can I remove the observer (A observing B)? View A's reference to view B gets nil'd out before I have a chance to remove it.
A outlives B since the view controller has a strong reference to A. Here's the leaking log message:
An instance 0x9ac5200 of class UITableView was deallocated while key value observers were still registered with it. Observation info was leaked, and may even become mistakenly attached to some other object. Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger. Here's the current observation info:
<NSKeyValueObservationInfo 0x8660360> (
<NSKeyValueObservance 0x8660320: Observer: 0x8660020, Key path: contentOffset, Options: <New: YES, Old: NO, Prior: NO> Context: 0x8660020, Property: 0x864ac80>
)
B is a UITableView. Setting a breakpoint at NSKVODeallocateBreak
yields useless results.
In A's removeFromSuperview
, I try to remove the observer but A's reference to B is already nil
.
Switching to unsafe_unretained
and do things more manually or calling [A removeFromSuperview]
in the view controller's dealloc
solves the problem. I'd like to know how to solve this using a weak
property though.
Here's the relevant code: https://gist.github.com/2822776
I find any kind of code required specially for this case really unnecessary as removal can be automated.
With the introduction of ARC, Apple should have provide automatic removal of observers that would fix cases like this, but unfortunately they didn't. But I've made my own category that adds this lacking feature: https://github.com/krzysztofzablocki/SFObservers I've explained how I did manage that on my blog: http://www.merowing.info/2012/03/automatic-removal-of-nsnotificationcenter-or-kvo-observers/
If you look at my solution you will notice, that it makes sure that original code is called, even if one of the methods call other ones, so that even if apple changes its internal behavior the category will still work fine :)
You could define an explicit weak property referencing the superview and then observe self
with a key path like @"propertyReferringSuperview.propertyOfSuperview"
? When you get a KVO notification, you check if self.propertyReferringSuperview == nil
and stop observing @"propertyReferringSuperview.propertyOfSuperview"
.
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