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
b...@cheeseman.name
_______________________________________________

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

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

Reply via email to