Swift Weak vs Unowned
何時使用Weak以及何時使用Unowned,通過示例。問題
在上一篇文章中,我們討論了如何使用自動引用計數(ARC)來管理iOS應用程序中的內存使用情況。但是,在某些情況下,由於保留周期,ARC無法從內存中釋放對象。
當2個對象彼此具有強引用並被保留時,保留周期就是這種情況,使ARC無法從內存中釋放這些對象並導致我們稱之為「內存泄漏」。
解
默認情況下,每當我們聲明變數時,它都被視為「強」,
為了避免保留周期,我們應該將這些變數聲明為「弱」或「無主」。本文主要關注的不是處理內存管理,如果您不熟悉該主題,請閱讀上一篇文章。
我們的重點是什麼時候使用弱,什麼時候更好地使用現實世界的例子。
弱與無主
根據Apple的文檔:
當閉包和它捕獲的實例將始終相互引用時,將閉包中的捕獲定義為無主引用,並且將始終同時取消分配。
相反,當捕獲的參考在將來的某個時刻變為零時,將捕獲定義為弱參考。弱引用始終是可選類型,並且在它們引用的實例被釋放時自動變為nil。這使您可以檢查它們在閉包體內是否存在。
弱和無主之間的主要區別在於,weak是可選的,而unowned是非可選的。
通過聲明它很弱,你可以處理在某些時候它在閉包內可能是零的情況。如果您嘗試訪問碰巧為零的無主變數,則會導致整個程序崩盤。因此,只有當你肯定變數將永遠存在於閉包附近時才使用無主。
無主
您之前可能已經聽過很多內容了,但是當你真的要肯定這個變數將永遠存在於封閉的時候,所以你可以毫無後顧之憂地使用無主?
讓我們看看下面的例子:
在上面的例子中,閉包不會比ViewController活得更多,在這種情況下,你可以自信地使用unowned。
弱
現在在下面的示例中,讓我們看看何時應該使用weak來避免崩盤:
在上面的例子中,你可以永遠不能確定ViewController將比閉包更多,因為關閉控制器後可能會發生網路調用響應,因此你絕對應該使用weak作為可選項以避免崩盤。
如果我們可以在所有情況下使用弱,那麼為什麼要使用無主並且冒應用程序崩盤的風險?根據蘋果的說法,答案很簡單:
如果捕獲的引用永遠不會變為nil,則應始終將其捕獲為無主引用,而不是弱引用。
無主是更快,允許不變性和非選擇性。
如果您不需要弱,請不要使用它。
結論
為了避免內存泄漏,我們應該將變數聲明為弱或無主,而不是強大的默認實現。
然而,它們之間的關鍵區別在於weak是一個可選類型,而unowned則不是,所以我們只應該在100%確定閉包具有相同的生命周期時才使用unowned,所以閉包只能到達變數是可達的。
參考
- Apple的文檔
- 堆棧溢出
閱讀我之前關於通過示例避免內存泄漏的文章
Swift:通過示例避免內存泄漏
在Swift中,自動引用計數(ARC)用於管理iOS應用程序中的內存使用情況。
每次你創建…黑客noon.com