Releasing CGImage (CGImageRef)
Core Foundation objects (which all Core Graphics objects are) do support autorelease.
The steps you describe should work just fine and not leak or over-release the object.
I use CFRelease
instead of specific-class release functions like CGImageRelease
, but purely as a matter of style. I just have to beware of NULL
: CGImageRelease
checks for NULL
, whereas CFRelease
will crash when passed NULL
. Using CGImageRelease
and its siblings means you don't have to worry about this.
I'm assuming you meant removeObject:forKey:
, not removeObject
(which doesn't exist and wouldn't have somewhere to specify an object anyway).
Rudi
Updated on June 04, 2022Comments
-
Rudi almost 2 years
I'm curious if I'm following proper memory management with CGImageRef, which I'm passing through several methods (since it's CG object, I assume it doesn't support autorelease). Memory management with non-NSObjects and interaction with other NSObjects is still somewhat new to me.
Here what I'm doing:
I'm creating the CGImageRef inside my image cache manager with CGBitmapContextCreateImage (retain count 1), and adding it to the NSMutableDictionary (retain count 2).
When CALayers use the image, I assign with layer.contents (retain count +1), and clearing contents with layer.contents = nil (retain count -1) before removing the layer.
Finally, when clearing the texture, I call CGImageRefRelease and [NSMutableDictionary removeObject] to have retain count as 0.
Is this a proper way to do so?
-
Rudi over 14 yearsThanks for the link, great resource, clarifies a lot. Docs mentioned that CGImageRelease won't cause an error if image is NULL, so sounded safer to go with. removeObject:forKey:, yes, that one.
-
benzado over 14 yearsThe document you link to doesn't support your claim. Some Core Foundation objects are "toll-free bridged" to Cocoa classes, but not all are. You can cast a
CFStringRef
to aNSString *
and vice versa, but you cannot do so withCGImageRef
andUIImage
. -
Nico over 14 yearsMy claim is that CF objects support
release
andautorelease
. That document explicitly says so: “Note from the example that the memory management functions and methods are also interchangeable—you can useCFRelease
with a Cocoa object andrelease
andautorelease
with a Core Foundation object.” Furthermore, the CGImage reference says that CGImage descends from CFType: developer.apple.com/iphone/library/documentation/… -
Nico over 14 yearsSo, in a nutshell, yes it does.
-
benzado over 14 yearsI thought it was referring to toll-free bridged objects, which are a subset of CFTypes, based on: "Table 1 provides a list of the data types that are interchangeable between Core Foundation and Foundation." Also, at the bottom of the page: "Note: Not all data types are toll-free bridged, even though their names might suggest that they are. For example, NSRunLoop is not toll-free bridged to CFRunLoop, NSBundle is not toll-free bridged to CFBundle, and NSDateFormatter is not toll-free bridged to CFDateFormatter." Are you saying you can cast any CFType to NSObject and autorelease it?
-
Nico over 14 yearsYes. The Carbon-Cocoa Integration Guide explicitly says that “you can use …
release
andautorelease
with a Core Foundation object”, and anything whose class descends from CFType is a Core Foundation object (as evidenced by the fact that you can use CF functions likeCFRetain
,CFCopyDescription
, etc. on it). -
Nico over 14 yearsThis isn't the same as toll-free bridging, though. You can't say
[myCGImage performSelectorOnMainThread:@selector(…) withObject:…]
, because a CGImage is not an NSObject. -
nielsbot almost 13 years
CFRelease()
≠CGImageRelease()
. I'm pretty sureCFRelease()
will crash if you passNULL
, however it's safe to passNULL
toCGImageRelease()
-
Nico almost 13 years@nielsbot: Good catch! I didn't know that at the time. I still use CFRelease (with
NULL
checks as appropriate) for style reasons, so I'll have to think about how to edit that into my answer.