2011-06-29 135 views
1

如下面的代碼中目標C:內存管理模塊的情況下

__block Loader *loader = [[Loader alloc]initWithResourcePath:self.resourcePath]; 

[loader setCompletionHandler:^(NSArray *anArray){ 
    self.answerArray=anArray; 
    [self reloadData]; 

}]; 

[loader getObjects]; 

我的問題,我如果我使用的塊想知道是關於內存管理。分析器告訴我有潛在的泄漏(因爲我爲我的裝載程序做了一個alloc/init)。我怎樣才能在這裏阻止泄漏?我試圖在最後釋放加載程序,但導致我的應用程序停止運行。任何意見都在這裏讚賞

+0

停止運作如何?你得到的錯誤是什麼?機率會幫助你找到問題的原因。 –

+0

是否有你將loader聲明爲__block的原因? –

回答

3

幾個問題:

  • 沒有理由loader被宣佈__block;你沒有重新分配塊,因此,__block是毫無意義的。

  • 泄漏是因爲你alloc/init裝載機,但從來沒有釋放

  • 不命名方法getSomething; get前綴是爲通過引用返回內容的方法保留的。就叫它objects。如果它應該觸發負載,則稱它爲loadperformLoad

如果它是異步的,那麼getObjects是毫無意義的。如果同步,則完成塊是毫無意義的。

如果loader要同步使用,release它在方法的末尾。如果它是asynchronous,則完成塊可以釋放它。請注意,在這種情況下使用__block仍然毫無意義;同時在完成塊中提到loader會創建一個保留週期,當您明確地在您的loader(因爲您在設置完成處理程序時您必須已經完成Block_copy()如果它將被使用首先是異步的)。

+0

我在ASIHTTPRequest的網站(http://allseeing-i.com/ASIHTTPRequest/How-to-use)上讀到它,在聲明請求時使用__block限定符是很重要的。但我是否正確地說這個例子是相關的,因爲他們實際上在塊中使用了請求? – Zhen

+0

是的,由於我之前描述的原因,只有當連接完成或錯誤時(即一旦塊不再被調用),他們才選擇不釋放塊,從而創建一個循環。我選擇使用週期自動被破壞的模式作爲對象生命週期的一部分。 – bbum

1

如果你打算使用loader以外的函數調用你的塊,很可能你需要將它存儲在你的控制器的ivar(我猜,它是一個控制器,但我不知道什麼樣的班級擁有你所顯示的代碼)。一旦你這樣做了,你可以在你的dealloc中發佈它。

推理是loader應該跨幾個方法和runloop循環,所以局部變量不會這樣做。

否則,只要在塊的末尾釋放它,一旦你完成了它。

如果這看起來不正確,那麼可能需要更多的代碼。

1

我打算做一些假設:1)完成處理程序(塊)由getObjects方法使用。 2)getObjects是異步的(儘管它繼續處理,它立即返回給調用者)。

有了這些假設,在發送getObjects之後無法發送發佈,因爲getObjects仍在使用完成處理程序。

嘗試在完成處理程序結束時發送release或autorelease。這應該免費裝載器提供reloadData也不是異步。