Re: Understanding CFMakeCollectable (was: EXC_BAD_ACCESS when -fobjc-gc)
Re: Understanding CFMakeCollectable (was: EXC_BAD_ACCESS when -fobjc-gc)
- Subject: Re: Understanding CFMakeCollectable (was: EXC_BAD_ACCESS when -fobjc-gc)
- From: Clark Cox <email@hidden>
- Date: Wed, 7 Oct 2009 17:01:21 -0700
On Wed, Oct 7, 2009 at 2:48 PM, Gabriel Zachmann <email@hidden> wrote:
> Thanks for your response.
>
>> No. CFRetain & CFRelease continue to work the same regardless of GC. That
>> is, the reference count field still exists, but Obj-C objects in GC start
>> life with a 0 retain count and -retain/-release/-retainCount/-autorelease
>> are no-op'd. CF objects still start life with a retain count of 1, and thus
>> you need to release them in order for them to participate in GC.
>
> So in other words, the purpose of CFMakeCollectable() is to decrease the
> ref-count to 0 in the GC world, and only there, is that correct?
>
>> Since you do not want to release them in a ref counted environment,
>> CFMakeCollectable (and NSMakeCollectable) need to do nothing in ref-counted
>> (or your objects would vanish) and CFRelease (not -release) in a GC
>> environment.
>
> So, when I have old code like this:
>
> CFTypeRef obj = CFCreateType( ... );
> // do something with obj
> CFRelease( obj );
>
> I always need to transform it into this:
>
> CFTypeRef obj = CFCreateType( ... );
> // do something with obj
> if ([NSGarbageCollector defaultCollector] == NULL )
> CFRelease( obj );
> CFMakeCollectable( obj );
No. you don't *need* to do anything. Under GC, the following two are
semantically identical:
CFTypeRef obj = CFCreateType( ... );
CFRelease( obj );
CFTypeRef obj = CFCreateType( ... );
CFMakeCollectable( obj );
If your object never passes through Obj-C code, and simply sticks to
the CF functions, *nothing* has to change about the way you retain and
release objects; it's only when you are mixing CF-style and ObjC-style
code that the difference matters.
If you're writing code that will only ever run as non-GC:
-retain and CFRetain are synonyms
-release and CFRelease are synonyms
CFMakeCollectable is a no-op
If you're writing code that will only ever run under GC:
You never need use -retain (it's a no-op)
You never need use -release (or -autorelease; they're no-ops)
CFMakeCollectable and CFRelease are synonyms (you can use it much like
you used -autorelease in non-GC code)
If your writing code that has to run both with and without GC, you
need to think carefully about what happens in both modes. For example,
say you have a old method that looks like this:
-(id)myObject {
return [(id)CFFooCreateObject(...) autorelease];
}
this will function just fine in the old, non-GC mode, but will "leak"
under GC. To fix this, you would change it to:
-(id)myObject {
return [NSMakeCollectable(CFFooCreateObject(...)) autorelease];
}
which does the right think in both cases. Under GC, it is semantically
equivalent to:
-(id)myObject {
return NSMakeCollectable(CFFooCreateObject(...));
}
and under non-GC, it is equivalent to the original method:
-(id)myObject {
return [(id)CFFooCreateObject(...) autorelease];
}
--
Clark S. Cox III
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