什么是缓冲区> CGImageRef-> UIImage的正确内存管理模式? [英] What's the right memory management pattern for buffer->CGImageRef->UIImage?

查看:202
本文介绍了什么是缓冲区> CGImageRef-> UIImage的正确内存管理模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数,它接受一些位图数据并从中返回一个UIImage *。它看起来像这样:

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];
}

任何人都可以确切地解释谁在这里拥有什么内存?我想要正确清理,但我不确定如何安全地进行清理。文档在这些上是模糊的。如果我在创建UIImage后在此函数结尾处 free 像素,然后使用UIImage,我崩溃了。如果我在创建UIImage之后释放提供者或imageRef,我没有看到崩溃,但他们显然已经将像素一直传递过来,所以我对释放这些中间状态感到不安。

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.

(我知道每个CF文档我需要在后者上调用release,因为它们来自Create函数,但我可以在使用UIImage之前执行此操作?)大概我可以使用提供者的dealloc回调来清理像素缓冲区,但还有什么呢?

(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?

谢谢!

推荐答案

这里的拇指规则是 -release *它,如果你不需要它。

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

因为之后你不再需要提供者 imageRef ,你应该 -release 所有这些,即

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];

像素不通过引用计数来管理,所以你需要告诉CG API在必要时为你释放它们。这样做:

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

顺便说一下,你可以使用 + imageWithCGImage:而不是 [[[* alloc] initWithCGImage:] autorelease] 。更好的是,有 + imageWithData:所以你不需要搞乱CG和 malloc 的东西。

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.

(*:除非 retainCount 从一开始就被认为是零。)

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

这篇关于什么是缓冲区> CGImageRef-> UIImage的正确内存管理模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆