Re: Tracking the retain count
Re: Tracking the retain count
- Subject: Re: Tracking the retain count
- From: Britt Durbrow <email@hidden>
- Date: Mon, 18 May 2015 16:25:52 -0700
>
> On May 18, 2015, at 11:38 AM, Quincey Morris <email@hidden> wrote:
>
> On May 18, 2015, at 10:52 , Britt Durbrow <email@hidden> wrote:
>>
>> Is the reasoning that:
>>
>> 1: Not under ARC;
>> 2: There is one known strong link to an object;
>> 3: retainCount returned 1
>>
>> Therefore, the only strong link to the object is the known strong link specified in item 2.
>>
>> … is that not valid? If not, why not?
>
> No, I think not. There are at least 2 dimensions of variability that can break this reasoning: time and threads. Furthermore, the assumption that your peek at the object state will reliably (or ever) return a retain count of 1 as opposed to (say) 2 is flawed. For example, if the object is in the autorelease pool, you’ll see a count of at least 2, but you won’t be able to deduce why.
>
The object graph is not thread-safe; so I don’t think that applies?
If some objects are in autorelease pools, that means that there is a strong link to them out there somewhere (presumably on the stack or in a register where it’s going to go away once the stack frames get popped) and the object pool controller shouldn’t let go of the object yet. Hopefully there will be enough else that can be released that the memory pressure gets satisfied. Also, I can set a flag to cause the object pool controller to re-scan the pool for objects to release after the main autorelease pool is drained in the main event loop.
>> Note that I am *not* asserting that it will be deallocated, just that nothing else has a strong link to it that could use it in a detrimental way (most importantly, mutate it).
>
> Just so, so I think you need to disentangle the following things:
>
> 1. Whether an object is in your data model’s object graph. Note that there is an implicit extended object graph beyond the references between the objects themselves. For example, if an object is (say) set as the delegate of some service, but is no longer in your actual object graph, it may get a delegate message that causes it to intrude unexpectedly. In that case, it’s effectively still in your object graph.
>
Right, which is why I can’t have the object pool controller just drop an object unless the pool controller is the only one with a strong link to the object.
> 2. Whether an object is alive (has or has not reached dealloc). You actually don’t care about this, though we haven’t convinced you of that yet. ;)
>
Actually what I care about is if anybody can access the object. I don’t care if it has reached dealloc yet or not. If the object is reachable, it has to keep it’s singular identity.
> 3. Whether an object is discardable from memory in case of (for example) memory pressure.
>
> Currently, you’re trying to achieve #1 and #3 by thinking in terms of #2. However, #2 is the one thing you can’t actually control — in any very direct and deterministic way.
I don’t think I need to control it per se, just catch a very specific case: that nothing has a strong link besides the one held by the object pool controller.
>
> You currently have an app that controls #1 directly. You’ve also been offered several ways of controlling #3 directly, one of which is to forcibly increment or decrement the retain count in deterministic ways. Your unease is making you think of this as an attempt at #2, but it’s not. It’s really #3.
>
>
I haven’t fully rejected the double pointer weak-link strategy… I’m just, as you said, uncomfortable with it, and don’t (as of yet) see it as *necessarily* less ugly than looking at retainCount in this very specific case...
***************************************************************************************************************************************************
> On May 18, 2015, at 11:25 AM, Ken Thomases <email@hidden> wrote:
>
> On May 18, 2015, at 12:52 PM, Britt Durbrow <email@hidden> wrote:
>
>> In order to maintain graph coherency the object pool controller must ensure that there is only ever one object in memory with a particular UUID. Consequently, I can’t just have the object pool controller release the objects without assurance that nothing else is going to keep it around (and potentially use it after the object pool controller has replaced it with another object with the same UUID, reloaded from disk).
>
> Can you have some sort of -invalidate method on the objects that puts them into a state where they can't be used or confused with a subsequently-loaded object? If necessary, it could clear the UUID or whatever.
>
> Regards,
> Ken
>
There is a large body of pre-existing code that relies on this system; in order to do that I would have to retrofit checks for validity onto every point where the object graph is accessed. At the very least, that’s a *major* project, time-wise, and is also probably a good way to introduce lots of bugs into two other large projects…
Also, just clearing the UUID doesn’t solve the problem, it’s what the UUID represents that must be unique (namely, the identity of the disk-backed object).
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden