Let me try and summarize where we are, in response to the several recent 
suggestions:

Britt has an app with an existing, fully functional custom cache of objects 
that have a UUID property, with the restriction that UUIDs are unique amongst 
objects in the cache. Objects may be created in various incarnations over time 
under the same UUID, but only one incarnation can be in the cache using the 
UUID at any moment.

In addition, because of the overhead of managing the uniqueness of the UUIDs, 
it’s too expensive to create new objects regularly on demand. The purpose of 
the cache is to extend the lifetime of otherwise unreferenced objects so that 
they can be reused rather than reincarnated. It does this by taking ownership 
of (retaining, keeping a strong reference to, however you want to think of it) 
every object in the cache.

This means that objects can exist in memory in one of these states:

— “Referenced". That is, there is a strong reference to the object somewhere 
else in the app’s object graph, beyond the cache’s owning reference.

— “Unreferenced". There is no strong reference to the object elsewhere in the 
app’s object graph. The only “known-for-sure” strong reference is the cache’s 
owning reference. Britt originally wanted to believe that this meant that the 
cache contained the only strong reference, period, but I called this out as 
invalid reasoning about retain counts, because there’s actually a 3rd case …

— “Inaccessible". There is a reference to the object somewhere else for some 
other housekeeping reason. The prime such housekeeping reason is being in the 
autorelease pool pending draining, but in theory objects may perhaps 
temporarily be referenced somewhere in the bowels of the frameworks. (This has 
to be temporary, otherwise these objects would be leaked, but the point of 
deallocation is theoretically unknown.)

I don’t have any other plausible housekeeping reasons, but I do know that “No 
one else should be using this object right now” is a common prelude to a 
self-inflicted injury.

Now, Britt wants to modify the cache so that is capable of discarding all 
unreferenced objects. Discarding the sole owning reference would have this 
effect, but it would also destroy the cache itself, so that’s not feasible.

The easiest solution to conceptualize is to give the cache both a strong 
(owning) and a weak reference to each object. Then, to purge the cache of 
unreferenced objects, all that’s necessary is to nil the strong references. 
Thereafter the unreferenced objects will, we hope, become deallocated, though 
some may remain merely inaccessible. In particular, any objects referred to by 
an autorelease pool won’t get deallocated until the pool is drained. Once 
that’s done, as far as the app’s concerned there should be no more inaccessible 
objects, but in reality we don’t know this for sure — vid. "housekeeping 
reasons" — and we have no valid way of *reasoning* them out of existence.

Still, armed with a belief that most if not all are deallocated, it’s now 
possible to re-establish the strong references in the cache, and things go 
along as before until the next time the cache needs to be purged.

All of this is non-controversial. The problem is solved. Except that Britt 
isn’t happy with the duplication of resources involved in that solution.

So, I’ve been trying to sell the idea that you only need one pointer — the weak 
one — and that the full effect of the strong pointer can be obtained by merely 
incrementing the retain count (once) when an object enters the cache. To purge 
the cache, decrement all the retain counts, drain the autorelease pools, then 
increment them again. There are a couple of ways of doing this in an ARC 
environment, but I (in a similar situation) use CFRetain (or perhaps 
CFBridgingRetain, can’t remember) because I’ve found it most readable.

Britt’s hesitant about this solution, too, because it apparently reasons about 
retain counts, which we’re told not to do, and I seem to have just finished 
saying so too. I claim that there’s no contradiction. It’s valid in this 
situation, because the only reasoning we’re doing is about *our* ownership 
reference, not about any others that we don’t control. Indeed, we’re not so 
much reasoning, as relying on the definition of ownership.

On May 18, 2015, at 17:27 , Graham Cox <graham....@bigpond.com> wrote:
> 
> just pointing you at NSDiscardableContent for a second, that has a 
> “pseudo-retain count” type of mechanism

I believe this is functionally identical to incrementing the actual retain 
counts, so it’d be a matter of personal preference which to use.

On May 18, 2015, at 17:48 , Roland King <r...@rols.org> wrote:
> 
> Perhaps I missed something germane in the discussion about why a simple 
> scheme like that doesn’t fulfil all requirements. 

Just that Britt wanted to avoid having two sets of pointers.

On May 18, 2015, at 19:46 , dangerwillrobinsondan...@gmail.com wrote:
> 
> if you've got so many objects that it is causing memory pressure

I think the memory pressure we’re talking about here is something like a 
low-memory warning because *other* apps are trying to use all the memory and 
we’re trying to be helpful. We’re not really talking about the case where the 
cache itself is absolutely too big.

[Apologies for the length of this post.]



_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to