When does an associated object get released?
Even larger than your -dealloc
issue is this:
UIKit is not KVO-compliant
No effort has been made to make UIKit classes key-value observable. If any of them are, it is entirely coincidental and is subject to break at Apple's whim. And yes, I work for Apple on the UIKit framework.
This means that you're going to have to find another way to do this, probably by changing your view layouting slightly.
The accepted answer to this related question explains the deallocation timeline of objects. The upshot is: Associated objects are released after the dealloc
method of the original object has finished.
what i think is happening in your case is this:
1) object A receives the -dealloc
call, after its retain count has gone to 0;
2) the association mechanism ensures that object B gets released (which is different from deallocated) at some point as a consequence.
i.e., we don't know exactly at which point, but it seems likely to me that this kind of semantic difference is the cause of object B being deallocated after object A; object A -dealloc
selector cannot be aware of the association, so when the last release on it is called, -dealloc
is executed, and only after that the association mechanism can send a -release
to object B...
have also a look at this post.
it also states:
Now, when objectToBeDeallocated is deallocated, objectWeWantToBeReleasedWhenThatHappens will be sent a -release message automatically.
I hope this helps explaining what you are experiencing. As to the rest, I cannot be of much help...
EDIT: just to keep on with such an interesting speculation after the comment by DougW...
I see the risk of having a sort of cyclic dependency if the association mechanism were "broken" when releasing object A (to keep going with your example).
if the association-related code were executed from the release method (instead of dealloc), for each release you would check if the "owning" object (object A) has a retain count of 1; in fact, in such case you know that decreasing its retain count would trigger dealloc, so before doing that, you would first release the associated object (object B in your example);
but what would happen in case object B were also at its turn "owning" a third object, say it C? what would happen is that at the time release is called on object B, when object B retain count is 1, C would be released;
-
now, consider the case that object C were "owning" the very first one of this sequence, object A. if, when receiving the release above, C had a retain count of 1, it would first try and release its associated object, which is A;
- but the release count of A is still 1, so another release would be sent to B, which still has a retain count of 1; and so on, in a loop.
If you, on the other hand, send the release from the -dealloc such cyclic dependency does not seem possible.
It's pretty contrived and I am not sure that my reasoning is right, so feel free to comment on it...