2013-06-29 136 views
6

我正在閱讀關於__block variables的文檔,並考慮了使用__block的情況。對我來說,這似乎是我需要它在兩種情況下:爲什麼__block變量不被保留(在非ARC環境中)?

  • 爲了紀念一個變量作爲讀寫塊
  • 內使用時,爲了避免塊內引用自當保留週期

從表面上看,這兩件事似乎並不相關。我認爲,__block變量不被保留爲我需要記住的避免保留週期的特定用例的更多技巧。

我想知道,是否有一個更重要的建築原因,爲什麼他們不能被保留?我認爲其他關鍵字可能會更清楚地表明這一點,以免混淆上面列出的兩個功能。

更新 -

我應該提到這是不使用ARC的代碼。我現在看到__block變量實際上保留在ARC中。

+2

您只使用'__block'作爲第一個。您可以使用'__weak'而不是'__block'來避免保留週期。 – rmaddy

+2

另外,你在哪裏得到__block變量不被保留的想法? ARC會自動保留它們,就像常規變量一樣。 –

+2

在ARC之前,__block變量確實不被保留爲避免保留週期的機制。這一點隨着ARC而改變,並記錄在轉換到ARC版本說明中。 –

回答

12

__block如果使用手動引用計數,則不會保留變量。究其原因可以在這裏找到:http://www.mikeash.com/pyblog/friday-qa-2009-08-14-practical-blocks.html

一個簡單的解決方法,這在於一個事實,即__block變量 不會被保留。這是因爲這樣的變量是可變的,而且它們的自動內存管理會要求每個變種都在後臺生成內存管理代碼。這被認爲是太侵入性並且難以正確地進行,特別是因爲同一塊 塊可能同時從多個線程執行。

,並在這裏:http://lists.apple.com/archives/objc-language/2009/Dec/msg00100.html

有沒有辦法在變量中的值的重新分配,以適當和有效管理保留計數 。

(我找不到蘋果文檔中的「官方」參考)

正如"Transitioning to ARC Release Notes"記載,這種行爲與ARC改變:

在手動引用計數模式, __block id x;的影響不是 保留x。在ARC模式下,__block id x;默認爲保留x(只有 與所有其他值一樣)。要獲得ARC下的手動引用計數模式 行爲,可以使用__unsafe_unretained __block id x;。 因爲名稱__unsafe_unretained意味着,但是,有一個 非保留變量是危險的(因爲它可能會晃),因此不鼓勵 。兩個更好的選擇是使用__weak(如果 您不需要支持iOS 4或OS X v10.6),或者將__block 的值設置爲nil以打破保留週期。

+0

不錯,這是有道理的。謝謝。 –

+0

@darren:在再次閱讀這些引用之後,似乎我認爲避免保留循環比__block變量的設計目標更具副作用。 –