2014-01-21 59 views
0

所以我有一些代碼在NSThread中運行,在循環中創建了一大堆NSImage s。每個圖像的一小部分被繪製到另一個NSImage,然後該線程退出。drawInRect保留NSImage直到將來的某個點?

所以,像

NSImage *outputImage = [[NSImage alloc] initWithSize:size]; 
[outputImage lockFocus]; 
while(1000 times) 
    NSImage* image = [[NSImage alloc] initWithSize:size]; 
    ... image is processed ... 
    [image drawInRect: ... fromRect: ... ] 
[outputImage unlockFocus]; 

一旦完成,該線程使用performSelectorOnMainThread到NSImage中創建發送回主線程將它放置在一個視圖。

這一切工作正常,最終的形象是完全如我所料。但是,在循環過程中,應用程序的內存使用量會線性上升 - 就好像每個NSImage直到稍後纔會釋放。我的理論是,drawInRect調用正在某處進行流水線調用,直到後來才實際執行。它是否正確?如果是這樣,我該如何預防它?如果我現在讓我的循環計數器過大,我的應用程序將崩潰,我想避免這種情況。

我試着將鎖定和解鎖的焦點放入循環中,但這沒有什麼區別。

我已經證實,如果我只拿出drawInRect調用,內存使用率(或多或少)在線程的整個生命週期內是平坦的。只有當我打電話時,記憶力纔會上升。

我(明顯?)在這個項目中使用ARC,它在OSX10.9中運行。

回答

2

這聽起來像你的NSImages在某些時候被添加到autorelease池。直到游泳池排水後,他們通常不會被沖洗。

在情況下,這樣的你想使自己的自動釋放池:

NSImage *outputImage = [[NSImage alloc] initWithSize:size]; 
[outputImage lockFocus]; 
while(1000 times) { 
    @autoreleasepool { 
     NSImage* image = [[NSImage alloc] initWithSize:size]; 
     ... image is processed ... 
     [image drawInRect: ... fromRect: ... ] 
    } 
} 
[outputImage unlockFocus]; 

這將創建一個子池,將獲得每通排水,所以你不會有一個巨大的積聚圖片。

+0

非常感謝 - 可能就是這樣。我感興趣,但我認爲自動引用計數操作很像使用boost :: shared_pointers無處不在(我來自C++背景)。所以,一旦某些事情超出了範圍,或者被分配了空值,它就會被釋放。我從你的評論中認爲ARC不是這種情況,我必須明確地聲明特殊塊來實現這一點。 –

+0

我相信有些情況下你可以完全避免自動釋放,但我不確定你的代碼在這種情況下觸發了什麼,如果它實際上是什麼讓你傷心。 –

+0

昨晚我嘗試了這個修復方法,它徹底清除了這個問題。不調用drawInRect也可以避免這個問題 - 當然它也會阻止代碼做任何事情。當我看起來可能需要它時,我只需要記住使用@autorelease。謝謝你的幫助。 –