簡體   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