Re: EXC_BAD_ACCESS when -fobjc-gc is on (Was: Memory corruption ...)
Re: EXC_BAD_ACCESS when -fobjc-gc is on (Was: Memory corruption ...)
- Subject: Re: EXC_BAD_ACCESS when -fobjc-gc is on (Was: Memory corruption ...)
- From: "Stephen J. Butler" <email@hidden>
- Date: Wed, 7 Oct 2009 17:25:09 -0500
On Wed, Oct 7, 2009 at 3:47 PM, Gabriel Zachmann <email@hidden> wrote:
> In the doc of CALayer.contents it says
>
> @property(retain) id contents
>
> Does a retained property always translate to a strong reference in a GC
> environment?
No, in GC a retain/release/autorelease always translates to a no-op.
An "id" or "SomeObject*" translates to a strong reference unless
specifically marked as weak.
> I tried this
>
> CGImageRef cgImage = CFMakeCollectable( CGImageSourceCreateImageAtIndex(
> sourceRef, 0, NULL ) );
> // [snip]
> imgLayer.contents = (id) cgImage;
> // [snip]
> CGImageRelease( cgImage );
> return imgLayer;
This you're over-releasing.
> CGImageRef cgImage = CGImageSourceCreateImageAtIndex( sourceRef, 0, NULL
> );
> // [snip]
> imgLayer.contents = (id) cgImage;
> // [snip]
> CFMakeCollectable( cgImage );
> return imgLayer;
>
> Both yield the same crash at the same place.
Hmm... re-reading the guide on CF and GC, I'm not so sure anymore that
this is your problem:
<http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/GarbageCollection/Articles/gcCoreFoundation.html#//apple_ref/doc/uid/TP40006687>
"If the object is in the garbage collected zone, the last CFRelease()
does not immediately free the object, it simply makes it eligible to
be reclaimed by the collector when it is discovered to be
unreachable—that is, 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 not be collected."
So if CGImage allocates things in a collectable zone (and it should)
then there shouldn't have been a problem originally. Still, if you're
going to stick with GC only then I'd re-write this as:
CGImageRef cgImage =
CFMakeCollectable(CGImageSourceCreateImageAtIndex( sourceRef, 0, NULL
));
// [snip]
imgLayer.contents = (id) cgImage;
// [snip]
return imgLayer;
> Did I misunderstand something?
>
> Or is the bug somewhere else?
Could be!
> In the guide it says that CFMakeCollectable() does a CFRelease() -- is that
> the same as a CGImageRelease() ?
Almost. Except CGImageRelease won't throw an exception if the
parameter is NULL, and CFRelease/CFMakeCollectable will.
>> But cgImage isn't collectable, so the strong reference does
>> nothing. Look at the documentaiton for CFMakeCollectable.
>
> I did that and there is one sentence that I don't understand at all:
>
> "CFMakeCollectable calls CFRelease, but has two supplementary features:
> [...]; second, it’s a no-op in a reference counted environment."
>
> Shouldn't that be "a no-op in a GC environment." ?
No, because CFRetain/Release still work the same as always in CG. It's
only the Foundation retain/release/autorelease that become no-ops.
_______________________________________________
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