Garbage Collection, Core Foundation, and the -finalize problem
Garbage Collection, Core Foundation, and the -finalize problem
- Subject: Garbage Collection, Core Foundation, and the -finalize problem
- From: Bill Cheeseman <email@hidden>
- Date: Mon, 16 Mar 2009 14:08:04 -0400
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.
In a reference counted environment, my class would simply implement a -
dealloc method that CFReleases the CFTypeRef ivar. I would use -
autorelease liberally in the usual fashion, and the CFTypeRef ivar
would get CFReleased automatically at the right time.
But in a garbage collected environment, according to the Garbage
Collection Programming Guide, I should do everything in my power to
avoid implementing a -finalize method. The Guide suggests that I
instead implement an -invalidate method to CFRelease the CFTypeRef
ivar, and then ensure that my -invalidate method is called whenever I
am finished with an instance of the class.
But the Guide gives no suggestions about how I can know when to call
the -invalidate method. Objects of my class are instantiated
frequently and I am quickly finished with them. I can think of no way
to call my -invalidate method automatically, as -autorelease would do
in a reference counted environment. I am not happy with the prospect
of having to place -invalidate calls throughout my code whenever the
logic seems to indicate that I am finished with a particular instance.
Garbage collection is supposed to make memory management easier, not
harder.
I see one Cocoa class that may deal with the same issue: NSEvent. In
Leopard, NSEvent includes methods to return the associated CGEventRef,
which is a CFTypeRef-style ivar (but declared as void* for reasons
that have so far escaped me). Comments in the header file indicate
that the CGEventRef is retained by the NSEvent and will be released
when the NSEvent is freed (I assume they mean CFRetained and
CFReleased). But I see no indication of how it accomplishes this.
I also see that NSConnection and NSPort implement -invalidate methods
that seem to be aimed at my problem. But the header files do not
reveal whether they are using CFTypeRef-style ivars. Furthermore, in
the NSConnection and NSPort contexts I suppose it is relatively easy
to know when to call -invalidate.
Should I conclude that this is a situation where the only usable
solution is to implement a -finalize method and throw all my releases
into it? My class does have lots of other objects to be released at
the same time, so this doesn't seem right because it will unduly
burden the collection process.
I should mention that my class is part of a mixed-mode framework that
must support both reference counted and garbage collected clients.
Any suggestions?
--
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