I\'m attaching object B via associative reference to object A. Object B observes some properties of object A through KVO.
The problem is that object B seems to be d
objc_getAssociatedObject()
for an OBJC_ASSOCIATION_RETAIN
association returns an autoreleased object. Might you be calling it earlier in the same runloop cycle / autorelease pool scope as object A is deallocated? (You can probably test this quickly by changing the association to NONATOMIC
).
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;
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...
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.