swift unowned和weak的使用

2021-09-24 07:51:52 字數 1727 閱讀 7824

通常的解釋是,考慮到物件的生命週期,您應該在unowned和weak之間進行選擇,但有時您可能仍然懷疑應該實際使用哪乙個,並且想知道unowned和weak哪乙個更好。

眾所周知,swift利用良好的舊arc(自動引用計數)來管理記憶體,因此,正如我們習慣使用objective-c一樣,我們必須通過明智地使用弱手動處理保留週期引用。

如果您不熟悉arc,則只需要知道每個引用型別例項都將具有與之關聯的引用計數(簡單整數值),這將用於保持物件例項當前的次數計數由變數或常數引用。一旦該計數器達到零,就會釋放例項,並且它們所擁有的記憶體和資源將再次可用。

每當兩個例項以某種方式相互引用時,您就有乙個保留週期(例如,兩個類例項具有引用另乙個類例項的屬性,如同雙鏈表中的兩個相鄰節點例項一樣)會阻止這些例項被釋放,因為保留計數總是大於零的值。

為了解決這個問題,在swift中以及在許多其他語言中,引入了弱引用的概念,arc不考慮這些引用,因此不會增加物件的保留計數。

考慮到弱引用不會阻止例項被釋放,因此必須始終記住,弱引用在任何時候都不能再指向有效物件。

swift有兩種弱引用:unowned和weak。

雖然它們用於相同的目的,但它們與您的例項生命週期相關的假設略有不同,並且具有不同的效能特徵。

在objective-c中,遵循標準模式,您將在塊外宣告對該例項的弱引用,然後在塊內宣告對該例項的強引用,以便在塊執行期間獲取它。顯然,檢查引用是否仍然有效是必要的。

為了幫助處理保留週期,swift引入了乙個新的構造來簡化並更明確地捕獲閉包內的外部變數,即捕獲列表。使用捕獲列表,您可以在函式頂部宣告將用於指定應在內部建立哪種引用的外部變數。

1.當您不使用捕獲列表時,閉包將建立對外部作用域的值的強引用:

閉包內發生的修改將改變原始變數的值

2.使用捕獲列表,建立乙個在閉包範圍內有效的新常量。

如果未指定捕獲修飾符,則常量只是原始值的副本,適用於值型別和引用型別。

在上面的例子中,我們icopy在呼叫之前宣告函式istrong,並且當宣告函式初始化私有常量時。如您所見,當我們呼叫第二個函式時,我們仍然會列印原始值i1。

3.指定具有引用型別的外部變數的名稱之前weak或unowned之前,此常量將被初始化為對原始值的弱引用,並且這種特定形式的捕獲是我們用來中斷保留週期的形式。

使用unowned時 永遠不會為nil 使用weak時 則是可選值

所以 如果這些物件的生命週期互不相關,也就是說,你不能保證哪一 個物件存在的時間會比另乙個⻓,那麼弱引用就是唯一的選擇。另一種情況下,如果你可以保證非強引用物件擁有和強引用物件同樣或者更⻓的生命週期的話,unowned 引用通常會更方便一些。這是因為我們可以不需要處理可選值,而且變數將可以被 let 宣告,而與之相對,弱引用必須被宣告為可選的 var。同樣的生命週期是很常⻅的,特別是當 兩個物體擁有主從關係的時候。當主物件通過強引用控制子物件的生命週期,而且你可以確定 沒有其他物件知道這個子物件的存在時,子物件對主物件的逆向引用就可以是 unowned 引用。

unowned 引用要比 weak 引用少一些效能損耗,因此訪問乙個 unowned 引用的屬性或者呼叫 它上面的方法都會稍微快一些;不過,這個因素應該只在效能非常重要的**路徑上才需要被 考慮。

unowned 引用帶來的不好的地方當然是如果你在生命週期的假設上犯了錯,那麼你的程式就將 崩潰。個人來說,我經常會在 unowned 也可以使用的情況下,還是去選擇用 weak。weak 將強制我們在所有使用的地方都去檢查引用是否依然有效。我們可能會時不時地對一些 **進行重構,而這可能會導致我們之前對於物件生命週期的假設失效。看你對哪一方面更重視

Swift unowned和weak的區別

unowned和weak均為避免出現迴圈引用 unownedunowned要求 獲的變數不能為nil,所以在closure中使用 unowned self 必須保證self不能為空,所以當self被釋放後再執行closure會導致程式崩潰。weakweak允許 獲的值為可選型,即可以 獲的值為nil...

imooc SpringBoot高階之Web高階

將通用邏輯從業務邏輯中分離出來 before註解 在方法執行之前執行 after註解 在方法執行之後執行 pointcut註解 設定切點,在其他攔截中直接呼叫log 方法 記日誌建議採用logger類中的幾個級別,而不是直接列印在控制台 記錄一次http請求及處理結果 記錄http請求的內容 bef...

Robot Framework 環境搭建(Web)

安裝步驟 1.安裝python 2.7.14 2.安裝wxpython 2.8 3.安裝pip 安裝robortframework ride pip install robotframework ride 安裝robotframework selenium2library pip install u...