What's the right memory management pattern for buffer->CGImageRef->UIImage?

core-foundation, core-graphics, iphone, quartz-2d, uiimage

Solution

The thumb rule here is "`-release`* it if you don't need it".

Because you no longer need `provider` and `imageRef` afterwards, you should `-release` all of them, i.e.

UIImage * image =  [[UIImage alloc] initWithCGImage:imageRef];
CGDataProviderRelease(provider);
CGImageRelease(imageRef);
return [image autorelease];

`pixel` is not managed by ref-counting, so you need to tell the CG API to free them for you when necessary. Do this:

void releasePixels(void *info, const void *data, size_t size) {
   free((void*)data);
}
....

CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixels, pixelBufferSize, releasePixels);

By the way, you can use `+imageWithCGImage:` instead of `[[[* alloc] initWithCGImage:] autorelease]`. Even better, there is `+imageWithData:` so you don't need to mess with the CG and `malloc` stuff.

(*: Except when the `retainCount` is already supposedly zero from the beginning.)

Problem

I have a function that takes some bitmap data and returns a UIImage * from it. It looks something like so: ``` UIImage * makeAnImage() { unsigned char * pixels = malloc(...); // ... CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixels, pixelBufferSize, NULL); CGImageRef imageRef = CGImageCreate(..., provider, ...); UIImage * image = [[UIImage alloc] initWithCGImage:imageRef]; return [image autorelease]; } ``` Can anyone explain exactly who owns what memory here? I want to clean up properly, but I'm not sure how to do it safely. Docs are fuzzy on these. If I `free` pixels at the end of this function after creating the UIImage, and then use the UIImage, I crash. If I Release the provider or the imageRef after creating the UIImage, I don't see a crash, but they're apparently passing the pixels all the way through, so I'm skittish about releasing these intermediate states. (I know per CF docs that I should need to call release on both of the latter because they come from Create functions, but can I do that before the UIImage is used?) Presumably I can use the provider's dealloc callback to cleanup the pixels buffer, but what else? Thanks!

Original source