我有一个功能,需要一些位图数据,并返回一个UIImage *从它。它看起来像这样:

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,我没有看到崩溃,但他们显然经过像素一路过关斩将,所以我水性杨花释放这些中间状态。

(我知道每个CF的文档,我应该需要调用两个后者的释放,因为他们来自创建功能,但我能做到这一点使用的UIImage前?)大概我可以利用供应商的dealloc的回调清理像素缓冲区,但还有什么?

谢谢!

有帮助吗?

解决方案

在经验法则这里是“-release *,如果你不需要它。”

由于您不再需要providerimageRef之后,你应该-release所有的人,即。

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

pixel不是由裁判计数管理的,所以你需要告诉CG API来释放他们为你需要的时候。做到这一点:

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东西乱七八糟。

(*:除了当retainCount已经推测从头零)

其他提示

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

您拥有pixels缓冲区,因为你mallocked它。

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

核心图形如下的核心基础的规则。你自己,因为你创建它的数据提供者。

您没有提供释放回调,所以你仍然拥有pixels缓冲区。如果你提供了一个释放的回调,则CGDataProvider对象将采取缓冲的所有权这里。 (通常是个好主意。)

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

您拥有CGImage对象,因为你创造了它。

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

您拥有UIImage对象,因为你allocked它。

您也仍然拥有CGImage对象。如果UIImage对象希望自己的CGImage对象,它要么保留,或使自己的副本。

return [image autorelease];

您放弃了自己的形象的所有权。

所以你的代码泄漏的像素(你没有所有权转移给数据提供者,你自己并没有释放出来),数据提供者(你不松开),和CGImage(你没有释放)。固定版本将转移像素所有权有关的数据提供者,并会释放两个数据提供者,由当时的UIImage准备的CGImage。或者,只要使用imageWithData:,作为KennyTM建议。

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

我也有使用malloc问题/免费使用CGImageCreate后 我终于找到好的和简单的解决方案。 我只替换行:

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

使用:

NSData *data = [NSData dataWithBytes:pixels length:pixelBufferSize];
CGDataProviderRef provider = CGDataProviderCreateWithCFData((CFDataRef)data);

只需后,我可以释放mallocked存储器:

free (pixels);

埃,该代码使我反胃。作为一个老规则生存的,我尽量不混合,并在同一个函数/方法/选择器匹配C和C ++和C / Objective-C的。

如何打破这种一分为二的方法。需要更改此makeAnImage到makeAnImageRef和UIImage的创作拉起到另一个对象 - 选择。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top