Re: [Leopard] Debugging GC
Re: [Leopard] Debugging GC
- Subject: Re: [Leopard] Debugging GC
- From: Chris Hanson <email@hidden>
- Date: Mon, 29 Oct 2007 17:10:30 -0700
On Oct 29, 2007, at 12:18 PM, glenn andreas wrote:
... you should balance CFRetain with CFRelease. That's it.
It use to be that if you called a CFCopy style routine, you could
return the result via autorelease, something like:
- (id) getSomethingFromCarbon
{
CFFooReference cffoo = CFCopyFooWithBar(5);
return [(id)cffoo autorelease];
}
(assuming CFFooReference was one of the bridged objects).
So what is the correct idiom now?
The correct idiom is now (following my own style, sorry):
- (id)somethingFromCarbon {
CFFooReference foo = CFCopyFooWithBar(5);
return [NSMakeCollectable(foo) autorelease];
}
CFMakeCollectable and its sibling NSMakeCollectable will:
* Under GC, invoke CFRelease() to balance the CFCreate/CFCopy and
return their argument.
* Under non-GC, just return their argument.
The only difference between CFMakeCollectable and NSMakeCollectable is
the return type; CFMakeCollectable returns a CFTypeRef while
NSMakeCollectable returns an id (eliminating a cast, as in your code
above).
Under garbage collection, the final CFRelease of an object DOES NOT
immediately cause that object to be collected, it simply makes it
eligible for collection once all strong references to it are gone.
Thus as long as the object is still referenced from an object-type
instance variable (that hasn't been marked as __weak), a register, the
stack, or a global variable, it will stay around.
When working with garbage collection, CFRetain and CFRelease can be
useful when you want to guarantee that an object stick around while
you can't guarantee there are strong references to it. One good
example is if you pass an object pointer as a sheet's (void *)context
parameter -- its (void *) type means it's not necessarily going to act
as a strong reference.
So you can CFRetain your object before passing it as the sheet's
context, and CFRelease it at the end of your sheetDidEnd:...
callback. Thus even though bringing up a sheet returns control to the
main run loop, and the collector may run a number of times before the
user finishes working in the sheet, your object will stick around
until the sheet is done and the -sheetDidEnd: callback is fired even
though the sheet's context may be the only place that references it.
-- Chris
_______________________________________________
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