Ben*_*tto 14 iphone core-graphics core-foundation uiimage quartz-2d
我有一个函数,它获取一些位图数据并从中返回一个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];
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以确切地解释谁在这里拥有什么记忆?我想要正确清理,但我不确定如何安全地进行清理.文档在这些上是模糊的.如果free
在创建UIImage之后我在此函数末尾的像素,然后使用UIImage,我崩溃了.如果我在创建UIImage之后释放提供者或imageRef,我没有看到崩溃,但他们显然已经完全传递了像素,所以我对释放这些中间状态感到不安.
(我知道每个CF文档我都需要在后者上调用release,因为它们来自Create函数,但是我可以在使用UIImage之前这样做吗?)大概我可以使用提供者的dealloc回调来清理像素缓冲区,还有什么?
谢谢!
ken*_*ytm 21
这里的拇指规则是" -release
*它,如果你不需要它".
因为你不再需要provider
和imageRef
之后,你应该-release
全部,即
UIImage * image = [[UIImage alloc] initWithCGImage:imageRef];
CGDataProviderRelease(provider);
CGImageRelease(imageRef);
return [image autorelease];
Run Code Online (Sandbox Code Playgroud)
pixel
不是通过引用计数来管理的,因此您需要告诉CG API在必要时为您释放它们.做这个:
void releasePixels(void *info, const void *data, size_t size) {
free((void*)data);
}
....
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixels, pixelBufferSize, releasePixels);
Run Code Online (Sandbox Code Playgroud)
顺便说一下,你可以用+imageWithCGImage:
而不是[[[* alloc] initWithCGImage:] autorelease]
.更好的是+imageWithData:
,你不需要弄乱CG和malloc
东西.
(*:除非retainCount
从一开始就认为是零.)
Run Code Online (Sandbox Code Playgroud)unsigned char * pixels = malloc(...);
您拥有pixels
缓冲区是因为您已将它集中在一起.
Run Code Online (Sandbox Code Playgroud)CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, pixels, pixelBufferSize, NULL);
Core Graphics遵循Core Foundation规则.您拥有数据提供者是因为您创建了它.
您没有提供发布回调,因此您仍然拥有pixels
缓冲区.如果您提供了发布回调,则CGDataProvider对象将在此处获取缓冲区的所有权.(通常是一个好主意.)
CGImageRef imageRef = CGImageCreate(..., provider, ...);
Run Code Online (Sandbox Code Playgroud)
您拥有CGImage对象是因为您创建了它.
UIImage * image = [[UIImage alloc] initWithCGImage:imageRef];
Run Code Online (Sandbox Code Playgroud)
您拥有UIImage对象,因为您已将其分配.
您还拥有CGImage对象.如果UIImage对象想拥有CGImage对象,它将保留它或制作自己的副本.
return [image autorelease];
Run Code Online (Sandbox Code Playgroud)
您放弃了对图像的所有权.
所以你的代码泄漏像素(你没有将所有权转移到数据提供者而你自己没有发布),数据提供者(你没有发布它)和CGImage(你没有发布它) .固定版本会将像素的所有权转移到数据提供者,并在UIImage准备好时释放数据提供者和CGImage.或者,imageWithData:
正如KennyTM建议的那样使用.
归档时间: |
|
查看次数: |
8221 次 |
最近记录: |