2012-10-27 62 views
2

首先,我沒有使用ARC,因爲我有更大的問題,我需要完全控制我的內存管理。加載很多遠程圖像 - 內存問題

以下是這種情況:我需要從服務器加載很多遠程JPEG圖像,並在滾動視圖中顯示它們。一旦用戶向下滾動一下,滾動視圖中的頂部圖像就會釋放。這是工作,包含的意見都是正常發佈。 問題是,加載遠程映像後,很多內存保持分配狀態並且沒有被釋放。 這裏是我的代碼來獲取遠程圖像(子類的UIImageView):

- (void)downloadImage { 
    NSData *posterData = [[NSData alloc] initWithContentsOfURL:self.url options:NSDataReadingUncached error:nil]; 
    UIImage *img = [[UIImage alloc] initWithData:posterData]; 
    [posterData release]; 
    self.image = img; 
    [img release]; 
} 
// that gets called from: 
- (void)setImageFromURL:(NSURL *)_url{ 
    [NSThread detachNewThreadSelector:@selector(downloadAndLoadImage) toTarget:self withObject:nil]; 
} 

當我檢查我與儀器的代碼,我的UIImageView被釋放的預期,但下面還是在我的記憶stucks和修建垃圾吧: Instruments http://s16.postimage.org/rybls16ed/Screen_Shot_2012_10_27_at_8_57_52_AM.png

顯然CFData,Malloc 9.00 KB,NSConcreteData都是由我的downloadImage方法產生的。 我在做什麼錯?這讓我瘋狂......你如何加載大量的遠程圖像內存安全? 我也嘗試NSURLConnection,但它是更糟,然後更好。 :(

圖像的大小變化提前6至25KB。

非常感謝!

UPDATE

我結束了使用SDWebImage它的偉大工程,是非常容易使用。

+0

你是如何聲明你的「'圖像'」屬性?此外,您嘗試下載的圖像有多大? –

+0

@MichaelDautermann圖像大小從6到25KB不等。 'image'屬性是'UIImageView'的正常圖像屬性 - 在這種情況下,我將子類UIImageView。 – christopher

回答

0

是否在後臺線程上下載圖像?如果是,那麼在哪裏是NSAutoreleasePool?您必須添加:

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; 

// your downloading thread code here 

[pool release]; 

或爲ARC:

@autoreleasepool {

// your downloading thread code here 

}

此外,如果圖像下載發生在後臺線程你不能做self.image = img;你應該把它在主線程,因爲UI元素只能從主線程修改:

[self performSelectorOnMainThread:@selector(setImage:) withObject:img waitUntilDone:YES]; 

其實SDWebImage library爲你做的一切,並有memcache和磁盤緩存

+0

我已經嘗試NSAutoreleasePool,並沒有改變。但感謝您在主線程中指出問題。我剛剛檢出了SDWebImageLibrary,並且改進了很多。 Malloc 9.00KB幾乎消失,但CFData仍然消耗大量內存。 – christopher

+0

我敢打賭,你不會放棄你的UIImageView的自定義子類的參考,並保留UIImage和NSData作爲結果。但是,根據您發佈的代碼無法知道。 – MoDJ