Releasing CGImage (CGImageRef)

16,888

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).

Share:
16,888
Rudi
Author by

Rudi

Updated on June 04, 2022

Comments

  • Rudi
    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
    Rudi over 14 years
    Thanks 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
    benzado over 14 years
    The 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 a NSString * and vice versa, but you cannot do so with CGImageRef and UIImage.
  • Nico
    Nico over 14 years
    My claim is that CF objects support release and autorelease. That document explicitly says so: “Note from the example that the memory management functions and methods are also interchangeable—you can use CFRelease with a Cocoa object and release and autorelease with a Core Foundation object.” Furthermore, the CGImage reference says that CGImage descends from CFType: developer.apple.com/iphone/library/documentation/…
  • Nico
    Nico over 14 years
    So, in a nutshell, yes it does.
  • benzado
    benzado over 14 years
    I 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
    Nico over 14 years
    Yes. The Carbon-Cocoa Integration Guide explicitly says that “you can use … release and autorelease 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 like CFRetain, CFCopyDescription, etc. on it).
  • Nico
    Nico over 14 years
    This 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
    nielsbot almost 13 years
    CFRelease()CGImageRelease(). I'm pretty sure CFRelease() will crash if you pass NULL, however it's safe to pass NULL to CGImageRelease()
  • Nico
    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.