2011-10-18 27 views
7

我正在讀的LLVM網站的ARC文檔:http://clang.llvm.org/docs/AutomaticReferenceCounting.html#autoreleasepool@autoreleasepool語義

..in講究@autoreleasepool。

在很多使用NSAutoreleasePool的當前實現中,我看到在循環迭代過程中池週期性耗盡的情況 - 我們如何對@autorelease池做同樣的事情,還是我們在某種程度上完成了這個任務?

其次,文檔聲明,如果引發異常,池不會被耗盡....好的異常是通過名稱例外的,但是如果它們確實發生,您可能希望在不泄漏負載的內存的情況下恢復。文檔沒有指定這些對象何時被釋放。

任何人都得到這些信息?

回答

9

在很多目前執行的使用NSAutoreleasePool,我看到那裏的池循環迭代期間定期排空的情況下 - 我們怎麼做@autorelease池相同,或者是這一切的引擎蓋下爲我們做了不知何故?

以同樣的方式,即通過級聯自動釋放池。例如:

@autoreleasepool { 
    … 
    for (int i = 0; i < MAX; i++) { 
     @autoreleasepool { 
      … 
     } 
    } 
    … 
} 

其次,文檔指出,如果有異常被拋出,池沒有耗盡....確定的例外是由特殊的名字,但如果他們不出現,你可能會喜歡在不泄漏內存的情況下恢復。文檔沒有指定這些對象何時被釋放。

在大多數情況下,由於可可中異常的特殊性,程序將無法正常恢復,所以我會說泄漏的對象是一個較小的問題。如果由於異常而退出@autoreleasepool塊,則只有當其中一個封閉自動釋放池被彈出時,相應的自動釋放對象纔會被釋放。但是,當然,您可以將@try/@catch/@finally塊放在@autoreleasepool塊內,以防止發生這種情況。

+0

我認爲你答案的第二部分是不完全正確的。自動釋放池本身在自動釋放池中有效地自動釋放,並在分配時有效。只要異常不會傳播到最外層的autorelease池之外,就不會有自動釋放的對象泄漏。 – JeremyP

+0

@Jer你是對的;謝謝你的提醒! – 2011-10-18 09:30:38

+0

@Bavarious - 謝謝你偉大的回答。這是肯定的,它使用'stringWithFormat'在循環中泄漏內存。 –

2

我們怎麼做同樣的@autorelease池

像這樣:

for (int i = 0; i < 10000; i++) { 
    @autoreleasepool { 
     // Do your work here 
     ... 
    } 
} 

其次,文檔指出,如果拋出一個異常,池ISN」噸排水....確定例外是名義例外,但如果他們確實發生,你可能想恢復沒有泄漏負荷的內存。

AFAIK這是ARC不可能的。 ARC根本不是特例安全的。如果發生異常,則可能會發生不可恢復的內存泄漏。使用ARC的代碼不應依賴異常來進行錯誤報告。期望的是,當發生異常時,進程崩潰。