Re: many-to-many relationships and retain cycles
Re: many-to-many relationships and retain cycles
- Subject: Re: many-to-many relationships and retain cycles
- From: Jens Alfke <email@hidden>
- Date: Mon, 2 Jun 2008 10:01:38 -0700
On 2 Jun '08, at 9:12 AM, Todd Ransom wrote:
An actor has a scenesForActor mutableArray and a scene has an
actorsForScene mutableArray. This all works great except that it
creates retain cycles and neither actor nor scene objects are ever
released if they have a relationship.
Yeah, this is a common design problem that comes up with ref-counted
object models.[1]
In general, if you don't have some sort of weak reference mechanism,
the solution is to explicitly tell an object to clean itself up when
it's being removed. In your app there is probably some kind of top-
level "Stage" or "Play" object that contains the scenes and actors; in
which case it probably has a "removeScene:" or "removeActor:" method.
That method could call a "removedFromStage" method on the object being
removed, which in turn would clear out its references to other objects.
In general, if a subgraph of your object graph can form a cycle, you
detect when that subgraph will be disconnected, and tell its objects
to break all the links between themselves that could form a cycle. (In
Smalltalk-80 this was a common enough task that there was a standard
method defined on Object to do this, that subclasses would override if
they had loopy references.)
It seems that what I need is a non-retaining array. I googled around
a bit and was surprised that I could not find an existing
implementation. It looks like I can create one by subclassing
NSMutableArray, overriding the primitive methods, and using a
CFArray as the backing store with NULL callbacks to avoid any kind
of retain or release when objects are added or removed.
It's even easier than that, thanks to CF/NS bridging. You can just use
the CFArray API to create an array with no-op retain/release
callbacks, and then cast the CFArrayRef to NSArray* and use it as an
NSArray.
—Jens
[1] It was a big issue in Smalltalk-80, especially because the runtime
could only handle 32,768 objects at once(!) and, worse, the runtime
was persistent: the way you saved was to snapshot the entire object
space to disk. So "lost" groups of cyclic objects would build up over
time, until you ran out of free object space. There was a tool that
did a real mark-and-sweep collection and would get rid of them, but
you had to let it run for a few hours. These were not fast machines by
today's standards...Attachment:
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________
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