簡體   English   中英

斯威夫特的弱勢與無足。 內部差異是什么?

[英]weak vs unowned in Swift. What are the internal differences?

我理解Swift中weakunowned之間的用法和表面差異:

我見過的最簡單的例子是,如果有一只Dog和一只BoneBone可能對Dog有弱引用(反之亦然),因為每種都可以彼此獨立存在。

另一方面,在HumanHeart的情況下, Heart可能對人類有一個unowned提及,因為只要Human變得“被解除引用”,就不能再合理地訪問Heart 這和CustomerCreditCard的經典例子。

所以這不是問題的重復。


我的問題是,有兩個這樣相似的概念有什么意義? 內部差異是什么,需要兩個關鍵字,看起來基本上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 letguard ,你可以檢查一個weak對零? 等等,但檢查一個unowned是沒有意義的,因為你認為這是不可能的。 如果你錯了,你會崩潰。

我發現在實踐中,我從不使用無主。 性能損失微不足道,但使用弱電的額外安全性對我來說是值得的。

我會將無用的用法留給需要優化的非常具體的代碼,而不是一般的應用程序代碼。

您正在尋找的“為什么存在”是Swift意圖能夠編寫系統代碼(如OS內核),如果他們沒有最基本的原語而沒有額外的行為,他們就不能這樣做。

注意:我之前在這個答案中已經說過,無主的並沒有設定為零。 這是錯的,一個裸露的unowned被設定為零。 unowned(unsafe)未設置為nil,可能是懸空指針。 這是為了滿足高性能需求,通常不應該在應用程序代碼中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM