邁克·阿什說:__bridge_transfer的相關描述;它是否避免了雙重保留?
當__bridge_transfer在鑄造時,它告訴ARC這個對象已經保留,而ARC不需要再保留它。自從ARC獲得所有權後,它在完成後仍會釋放它。
鏘文檔說:
(__bridge_transfer T)運算連鑄操作數,其必須具有非可保持指針類型,到目的地的類型,它必須是一個可保持對象指針類型。 ARC將在封閉的完整表達式的末尾釋放該值,這取決於對本地值的通常優化。
沒有在Clang文檔中說它__bridge_transfer避免了雙重保留。它只是表示該對象將在未來某個時間發佈。
這是爲什麼?考慮以下代碼片段:
NSString *value = (__bridge_transfer NSString *)CFPreferencesCopyAppValue(CFSTR("someKey"), CFSTR("com.company.someapp"));
CFStringRef從retainCount +1開始。將其分配給值時,CFStringRef會再次被保留,因爲默認情況下,會強烈引用value
。這導致了雙重保留。在範圍的最後,一個-release被髮送到value
,但是沒有其他任何東西可以平衡CFPreferences * 複製 * AppValue的滯留,從而導致內存泄漏。
__bridge_transfer
如何避免雙保留?
Clang的文檔並不會說「當__bridge_transfer用於演員時,它告訴ARC此對象已被保留,並且ARC不需要再保留它「。這意味着存在一些內置智能,ARC認識到我們即將分配給強引用類型,並隨後吃掉-retain消息以避免雙重保留。它是否正確? – 2012-07-23 21:42:40
爲了補充一點,是的,我同意在演員陣容上不會執行任何保留。但是在賦值爲'value'時會出現保留。 – 2012-07-23 21:44:46
@nessup:我應該澄清一下:Clang文檔明確聲明該值將在完整表達式的末尾釋放。這基本上意味着「這是一個擁有的價值」。演員陣容中沒有保留,但之後有一個釋放。隨後分配給局部變量將保留第二次,但當該變量超出範圍時也會有第二次釋放。優化器將識別雙重保留並將其刪除,因此您將剩下一個保留(並且在該範圍末尾有一個單獨的版本)。 – 2012-07-23 22:08:45