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