views:

36

answers:

2

I'm creating an bitmap context, and in my code there is this:

bitmapData = malloc(bitmapByteCount);

context = CGBitmapContextCreate (bitmapData,
                                     pixelsWidth,
                                     pixelsHeight,
                                     8,      // bits per component
                                     bitmapBytesPerRow,
                                     colorSpace,
                                     kCGImageAlphaPremultipliedFirst);

before the method returns the CGContextRef object, I think I must release the bitmapData. Can I safely call free(bitmapData) before I return the context?

+1  A: 

The documentation for CGBitmapContextCreate says this:

In iOS 4.0 and later, and Mac OS X v10.6 and later, you can pass NULL if you want Quartz to allocate memory for the bitmap. This frees you from managing your own memory, which reduces memory leak issues.

I would suggest you pass NULL instead of a malloc'd pointer and you will be free of worrying about its memory.

However, be mindful that CGBitmapContextCreate has 'create' in its name, so by convention you will own the object returned. You will need to release this at some point with CFRelease().

Jasarien
Isn't it actually the other way around? If there's "create" in the method name, you must autorelease it so the receiver doesn't have to worry about memory management. Only if it's "new" in the method name or "alloc" then you must release manually. At least that's what I learned ;)
openfrog
This question: http://stackoverflow.com/questions/870243/releasing-core-foundation-object-references explains a few things about releasing objects in Core Foundation. There is no concept of autorelease in Core Foundation.
Jasarien
From an answer in that question I linked: "Since there is no autorelease equivalent in Core Foundation, if you are returning the a reference from a method, return the array without releasing it. You should (unless you're being evil) then include "create" in the method name to indicate to the caller that they now own a reference to the returned object."
Jasarien
openfrog: You're thinking of methods. `CGBitmapContextCreate` is a function. Moreover, since it's in Core Graphics, it follows the Core Foundation memory-management rules (which are mostly the same, just Create instead of `new`/`alloc` and no autorelease). http://developer.apple.com/mac/library/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/ The essential truth remains the same: Whatever owns the context must release it, one way or another.
Peter Hosey
A: 

Jasarien's answer is best if you're developing for iOS version 4.0 or newer. If you want to support older versions, then keep reading.

You have to keep the bitmapData around as long as the context is being used. If you try to draw into the bitmap context and you've freed bitmapData, Bad Things will happen. The best solution is to free bitmapData after you call CFRelease on the context. If you called CGBitmapContextCreateImage to extract a CGImage from the bitmap context then don't worry... when you release the bitmap context, the CGImage will make its own copy of the bitmap data.

What this means is that making a method or function that creates and returns a bitmap context might not be the greatest idea. If you can, it would be best to create the context at the top of the method, use it in that methpd, and then release the context and free the bitmap at the end of the method. If you can't do that, consider storing the context and its bitmapData in ivars. If you need multiple bitmap contexts at one time, you'll probably want to create an object to track the context and its bitmapContext.

This is why it's best to pass NULL for the bitmapData if you're only supporting iOS version 4.0 or newer. If you're on 4.0+ and pass NULL, you can safely ignore the stuff I said above and just make sure that the caller eventually calls CFRelease on the context you return.

Jacques