Re: Garbage Collection, Core Foundation, and the -finalize problem
Re: Garbage Collection, Core Foundation, and the -finalize problem
- Subject: Re: Garbage Collection, Core Foundation, and the -finalize problem
- From: Bill Cheeseman <email@hidden>
- Date: Mon, 16 Mar 2009 15:53:14 -0400
On Mar 16, 2009, at 2:32 PM, Michael Tsai wrote:
On Mar 16, 2009, at 2:08 PM, Bill Cheeseman wrote:
I am looking for a strategy to avoid implementing a -finalize
method in a garbage-collected Objective-C class that declares a
CFTypeRef-style Core Foundation instance variable. I believe this
is a fairly common problem, because any Cocoa wrapper class for a
Core Foundation API would have to do it, but I haven't seen a
usable solution. Apple's GC documentation stops just short of
suggesting an answer.
I believe you're supposed to declare your CFTypeRef ivar as __strong
and call CFMakeCollectable so that the garbage collector will be
responsible for releasing it. You can still use CFRelease in -
dealloc for when you aren't running under garbage collection.
That's my understanding, as well, but it doesn't respond to my
question. I know how to make my CFTypeRef ivar collectable -- just
decrement its retain count to 0, which is all that CFMakeCollectable
does. What I need to know is how and when to release all the other
associated objects that must be released when I am through with the
ivar. The Apple Garbage Collection Programming Guide tells us to do
this in an -invalidate method and to ensure that it is called at an
appropriate time, but I see no convenient way to know when that time
has come.
As I understand it, CFMakeCollectable is an OPTIONAL means to satisfy
the need to CFRelease a CFTypeRef ivar, useful in situations where it
is reasonable to CFRelease the ivar immediately after it is created
and let GC decide when to actually collect it. To make its use
clearer, I think CFMakeCollectable should have been named
CFReleaseAndTherebyMakeEligibleForCollection. It does NOT "make a
CFTypeRef ivar collectable" by performing some magic that turns it
into a different kind of object. Instead, it "makes the ivar
collectable" ONLY by immediately CFReleasing it so as to decrement its
retain count to 0, which is a prerequisite to its being collected by
the garbage collector. In my case, I chose not to call
CFMakeCollectable, but instead to manage my internal CFRelease calls
myself -- because my framework was originally written for the
reference counted environment, and the CFRelease calls are already in
all the right places. Unlike Objective-C's -release method, CFRelease
works both under reference counting and garbage collection. It is
therefore easier to convert an existing reference counted framework to
support GC by foregoing use of CFMakeCollectable. (Somebody tell me if
I've got this wrong. The Guide is certainly confusing about this, and
as always I am acutely aware that I might have read it wrong.)
But either way, I am still faced with the question of when to call -
invalidate. I can't call it right after creating the CFTypeRef ivar,
because my -invalidate method releases other objects in addition to
the CFTypeRef ivar, and those other objects must remain in existence
until I am really finished with the ivar -- and, remembering that this
is GC, it does other things, too, that should be done at the right
time. That's why, as I understand it, Apple tells us to implement an -
invalidate method to do this at the right time -- neither too early
nor too late. But Apple doesn't tell us how to know when that is.
Doing it in a -finalize method would ensure that all the objects get
released only after they're no longer needed, but it would pile an
awful lot of work onto the collector, which Apple discourages.
--
Bill Cheeseman
email@hidden
_______________________________________________
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