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

后端 未结 4 1858
Happy的楠姐
Happy的楠姐 2021-02-07 14:11

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          


        
4条回答
  •  滥情空心
    2021-02-07 14:39

    unsigned char * pixels = malloc(...);
    

    You own the pixels buffer because you mallocked it.

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

    Core Graphics follows the Core Foundation rules. You own the data provider because you Created it.

    You didn't provide a release callback, so you still own the pixels buffer. If you had provided a release callback, the CGDataProvider object would take ownership of the buffer here. (Generally a good idea.)

    CGImageRef imageRef = CGImageCreate(..., provider, ...);
    

    You own the CGImage object because you Created it.

    UIImage * image =  [[UIImage alloc] initWithCGImage:imageRef];
    

    You own the UIImage object because you allocked it.

    You also still own the CGImage object. If the UIImage object wants to own the CGImage object, it will either retain it or make its own copy.

    return [image autorelease];
    

    You give up your ownership of the image.

    So your code leaks the pixels (you didn't transfer ownership to the data provider and you didn't release them yourself), the data provider (you didn't release it), and the CGImage (you didn't release it). A fixed version would transfer ownership of the pixels to the data provider, and would release both the data provider and the CGImage by the time the UIImage is ready. Or, just use imageWithData:, as KennyTM suggested.

提交回复
热议问题