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: Todd Ransom <email@hidden>
- Date: Mon, 02 Jun 2008 16:15:07 -0400
Thanks guys. I decided to just use CFArrayCreateMutable in my accessor
instead of creating a subclass and it's working beautifully.
Todd Ransom
Return Self Software
http://returnself.com
On Jun 2, 2008, at 1:01 PM, Jens Alfke wrote:
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...
_______________________________________________
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