protocol - swift delegate用法




我如何在'純粹'Swift中創建一個弱協議引用(沒有@objc) (4)

weak引用在Swift中似乎不起作用,除非protocol被聲明為@objc ,我不想在純Swift應用程序中使用它。

此代碼給出了編譯錯誤( weak不能應用於非類型MyClassDelegate ):

class MyClass {
  weak var delegate: MyClassDelegate?
}

protocol MyClassDelegate {
}

我需要在@objc該協議,然後才能正常工作。

問題:完成weak delegate的“純粹”快捷方式是什麼?


補充答案

我一直對代表是否應該軟弱表示困惑。 最近我了解了更多關於代表和什麼時候使用弱引用的內容,因此為了未來的觀眾,讓我在這裡添加一些補充點。

  • 使用weak關鍵字的目的是為了避免強烈的參考週期(保留週期)。 當兩個類實例具有強相互引用時,會產生強參考週期。 他們的引用計數永遠不會歸零,因此他們永遠不會被釋放。

  • 如果委託是一個類,則只需使用weak 。 Swift結構和枚舉是值類型(它們的值在新實例創建時被複製),而不是引用類型,因此它們不會產生強大的引用周期。

  • weak引用總是可選的(否則你會使用unowned )並且總是使用var (不允許),這樣可以在釋放時將可選項設置為nil

  • 父類自然應該對其子類有強烈的引用,因此不使用weak關鍵字。 但是,當孩子想要引用其父母時,應該使用weak關鍵字使其成為弱引用。

  • 當你想要引用一個你不擁有的類時,應該使用weak ,而不僅僅是引用其父類的子類。 當兩個非等級類需要相互引用時,選擇一個弱。 你選擇的取決於情況。 有關詳情,請參閱此問題的答案。

  • 作為一般規則,代表應該被標記為weak因為大多數代表正在引用他們不擁有的類。 當孩子使用委託與父母通信時,這當然是正確的。 但是,仍然有一些情況下 ,代表可以並應該使用強有力的參考。

  • 協議可以用於引用類型 (類)和值類型 (結構體,枚舉)。 因此,在需要使委託變弱的情況下,您必須將class關鍵字添加到協議中,以便它知道它只能用於引用類型。

    protocol MyClassDelegate: class {
        // ...
    }
    
    class SomeClass {
        weak var delegate: MyClassDelegate?
    }
    

進一步研究

閱讀以下文章有助於我更好地理解這一點。 他們還討論了相關問題,如unowned關鍵字和關閉時發生的強引用周期。

有關


Apple使用“NSObjectProtocol”而不是“class”。

public protocol UIScrollViewDelegate : NSObjectProtocol {
   ...
}

這也適用於我,並刪除了我在嘗試實現自己的委託模式時看到的錯誤。


更新:它看起來像手冊已更新,我所指的例子已被刪除。 請參閱上面編輯@ flainez的回答。

原文:即使您不與Obj-C互操作,使用@objc也是正確的做法。 它確保您的協議正在應用於類而不是枚舉或結構。 請參閱手冊中的“檢查協議一致性”。


您需要將協議的類型聲明為class

protocol ProtocolNameDelegate: class {
    // Protocol stuff goes here
}

class SomeClass {
    weak var delegate: ProtocolNameDelegate?
}

我的理解是,使用class ,你保證這個協議將只用於類和沒有其他東西像枚舉或結構。





swift-protocols