繁体   English   中英

为什么用CGImageSource加载gif会导致内存泄漏?

[英]Why does loading a gif with CGImageSource cause a memory leak?

我的项目中有一个gif文件。 我试图在我的UIImageView显示该gif文件。 这是我的代码:

NSData* gifOriginalImageData = [NSData dataWithContentsOfURL:url];// url of the gif file
CGImageSourceRef src = CGImageSourceCreateWithData((CFDataRef)gifOriginalImageData, NULL);

NSMutableArray *arr = [[NSMutableArray alloc] init];

NSInteger imagesCountInGifFile = CGImageSourceGetCount(src);
CGImageRef imagesOut[imagesCountInGifFile];
for (int i = 0; i < imagesCountInGifFile; ++i) {
    [arr addObject:[UIImage imageWithCGImage:CGImageSourceCreateImageAtIndex(src, i, NULL)]];
}

self.onboardingImageView.animationImages = arr;
self.onboardingImageView.animationDuration = 1.5;
self.onboardingImageView.animationRepeatCount = 2;
[self.onboardingImageView startAnimating];

我可以使用此代码成功显示gif文件。 但是,这会导致60张图像的最大内存泄漏为250mb。 我试图用给定的代码减少内存,但是再也没有成功。

self.onboardingImageView.animationImages = nil;
CFRelease(src);

任何帮助,将不胜感激。 编辑:我添加了 图片 这是潜在的泄漏。

如果函数中包含“ Create ”一词,则表明您有责任释放它返回的内容。 在这种情况下, CGImageSourceCreateImageAtIndex 的文档明确指出:

返回一个CGImage对象。 您有责任使用CGImageRelease释放此对象。

您反复调用CGImageSourceCreateImageAtIndex ,但从未实际释放它返回的CGImage ,因此导致内存泄漏。 一般的经验法则是,每次调用函数中都带有“ Create ”一词的函数时,都应该有一个等效的版本。

我也看不到拥有CGImages数组的CGImages (在创建UIImages数组时)。 这意味着您要做的就是在循环的每次迭代中创建CGImage ,将其包装在UIImage ,将此图像添加到数组中,然后最终释放CGImage 例如:

CGImageSourceRef src = CGImageSourceCreateWithData((__bridge CFDataRef)gifOriginalImageData, NULL);

NSMutableArray *arr = [[NSMutableArray alloc] init];

NSInteger imagesCountInGifFile = CGImageSourceGetCount(src);
for (int i = 0; i < imagesCountInGifFile; ++i) {
    CGImageRef c = CGImageSourceCreateImageAtIndex(src, i, NULL); // create the CGImage
    [arr addObject:[UIImage imageWithCGImage:c]]; // wrap that CGImage in a UIImage, then add to array
    CGImageRelease(c); // release the CGImage <- This part is what you're missing!
}

CFRelease(src); // release the original image source

请注意,您还应该桥接gifOriginalImageData而不是强制转换(我假设您正在使用ARC)。

进行更改后,以上代码可以正常运行,而不会发生任何内存泄漏。

您将要使用NSData数组和UIImage数组。 图像数据默认情况下是压缩的,并且使用UIImage可以解压缩数据。

同样,UIImage在后台有一些缓存,可能很难存储。

迈克尔·贝汉(Michael Behan)就该主题写了一篇很棒的博客文章: http : //mbehan.com/post/78399605333/uiimageview-animation-but-less-crashy

他写了一个有用的库(MIT许可证)来防止这种情况的发生: https : //github.com/mbehan/animation-view

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM