首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么用CGImageSource加载gif会导致内存泄漏?

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

Stack Overflow用户
提问于 2016-05-06 13:55:48
回答 2查看 1.1K关注 0票数 1

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

代码语言:javascript
复制
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文件。然而,它会导致高达250 to的内存泄漏,有60幅图像。我尝试用给定的代码来减少内存,但是没有成功。

代码语言:javascript
复制
self.onboardingImageView.animationImages = nil;
CFRelease(src);

任何帮助都将不胜感激。编辑:我添加了一个

这可能是个漏洞。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-06 16:24:46

如果一个函数中包含单词Create,这表明您有责任释放它返回的东西的内存。在这种情况下,文献资料 of CGImageSourceCreateImageAtIndex明确表示:

返回一个CGImage对象。您负责使用CGImageRelease发布此对象。

您正在反复调用CGImageSourceCreateImageAtIndex,但实际上从未释放它返回的CGImage,因此导致内存泄漏。一般的经验法则是,每次调用包含单词Create的函数--您应该有一个等效的版本。

我也不认为有一个CGImages数组的意义(因为您创建了一个UIImages数组)。这意味着您所要做的就是在循环的每一次迭代中创建您的CGImage,将其包装在一个UIImage中,将这个映像添加到您的数组中,然后最终释放CGImage。例如:

代码语言:javascript
复制
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)。

通过这些更改,上述代码在没有任何内存泄漏的情况下运行良好。

票数 4
EN

Stack Overflow用户

发布于 2016-05-06 14:15:05

您将希望使用NSData数组与UIImage数组。默认情况下压缩图像数据,并使用UIImage解压缩数据。

此外,UIImage在引擎盖下有一些缓存,可能会对内存造成困难。

Michael写了一篇伟大的博客文章,主题是:http://mbehan.com/post/78399605333/uiimageview-animation-but-less-crashy

他还写了一个有用的图书馆(麻省理工学院许可证)来防止这种情况发生:https://github.com/mbehan/animation-view

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37074253

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档