When does an associated object get released?

前端 未结 4 1856
无人及你
无人及你 2020-11-27 12:32

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

相关标签:
4条回答
  • 2020-11-27 12:37

    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).

    0 讨论(0)
  • 2020-11-27 12:38

    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.

    0 讨论(0)
  • 2020-11-27 12:38

    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).

    1. 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);

    2. 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;

    3. 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;

      1. 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...

    0 讨论(0)
  • 2020-11-27 12:54

    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.

    0 讨论(0)
提交回复
热议问题