[英]What's the difference in Swift between unowned vs weak but implicitly unwrapped?
[英]weak vs unowned in Swift. What are the internal differences?
我理解Swift中weak
和unowned
之間的用法和表面差異:
我見過的最簡單的例子是,如果有一只Dog
和一只Bone
, Bone
可能對Dog
有弱引用(反之亦然),因為每種都可以彼此獨立存在。
另一方面,在Human
和Heart
的情況下, Heart
可能對人類有一個unowned
提及,因為只要Human
變得“被解除引用”,就不能再合理地訪問Heart
。 這和Customer
和CreditCard
的經典例子。
所以這不是問題的重復。
我的問題是,有兩個這樣相似的概念有什么意義? 內部差異是什么,需要兩個關鍵字,看起來基本上99%相同的東西? 問題是為什么存在差異,而不是存在差異。
鑒於我們可以設置一個這樣的變量: weak var customer: Customer!
變量weak var customer: Customer!
, unowned
變量是非可選的優點是一個有爭議的問題。
我能看到的唯一實用優勢是使用
unowned
vs隱式地展開weak
變量!
是我們可以通過let
使unowned
引用不變。
......也許編譯器可以為此做出更有效的優化。
這是真的,還是在幕后發生了其他事情,為保留兩個關鍵詞提供了令人信服的論據(盡管略有區別 - 基於Stack Overflow流量 - 顯然讓新的和經驗豐富的開發人員感到困惑)。
我最感興趣的是聽過那些使用過Swift編譯器(或其他編譯器)的人。
我的問題是,有兩個這樣相似的概念有什么意義? 內部差異是什么,需要兩個關鍵字,看起來基本上99%相同的東西?
它們完全沒有相似之處。 它們盡可能地不同。
在引入ARC時引入的weak
是一個非常復雜的概念。 它執行近乎神奇的任務,允許您阻止保留一個循環(通過避免強引用),而不會在引用的對象不存在時冒着懸空指針的崩潰 - 這種情況曾經發生在ARC之前的所有時間被介紹了。
另一方面, unowned
非 -ARC弱(具體而言,它與非ARC assign
相同)。 這是我們曾經有過的風險是什么,這是什么原因造成這么多的崩潰,引入了ARC之前。 這是非常危險的,因為如果被引用的對象熄滅存在的,你可以得到一個懸空指針和崩潰。
差異的原因在於,為了執行其奇跡, weak
,涉及運行時的大量額外開銷,由編譯器插入幕后。 weak
引用是由內存管理的。 特別是,運行時必須維護以這種方式標記的所有引用的暫存器 ,跟蹤它們,以便如果弱引用的對象不存在,運行時可以找到該引用並將其替換為nil
以防止懸空指針。
因此,在Swift中, weak
引用始終為Optional(完全可以替換為nil
)。 這是額外的開銷來源,因為使用Optional需要額外的工作,因為必須始終打開它才能完成任務。
出於這個原因,無論何時適用,總是優先考慮unowned
。 但除非絕對安全,否則永遠不要使用它! 擁有unowned
,您將丟棄自動內存管理和安全性 。 你故意回到ARC之前的舊日。
在我的使用中,常見的情況出現在閉包需要涉及self
的捕獲列表以避免保留周期的情況下。 在這種情況下,幾乎總是可以在捕獲列表中說[unowned self]
。 當我們這樣做時:
這對程序員來說更方便,因為沒有什么可以解開的。 [weak self]
將是一個可選的需要展開才能使用它。
它的效率更高,部分出於同樣的原因(解包總是增加額外的間接級別),部分原因是因為它只是運行時的暫存器列表中較少的弱引用來跟蹤。
weak
引用實際上設置為nil,並且必須在引用釋放並且unowned
引用設置為nil時檢查它,但是您不必強制檢查它。
if let
, guard
,你可以檢查一個weak
對零?
等等,但檢查一個unowned
是沒有意義的,因為你認為這是不可能的。 如果你錯了,你會崩潰。
我發現在實踐中,我從不使用無主。 性能損失微不足道,但使用弱電的額外安全性對我來說是值得的。
我會將無用的用法留給需要優化的非常具體的代碼,而不是一般的應用程序代碼。
您正在尋找的“為什么存在”是Swift意圖能夠編寫系統代碼(如OS內核),如果他們沒有最基本的原語而沒有額外的行為,他們就不能這樣做。
注意:我之前在這個答案中已經說過,無主的並沒有設定為零。 這是錯的,一個裸露的unowned
被設定為零。 unowned(unsafe)
未設置為nil,可能是懸空指針。 這是為了滿足高性能需求,通常不應該在應用程序代碼中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.