簡體   English   中英

Swift協議和類的弱引用

[英]Swift protocol & weak references with class

如果我有一個協議:

protocol SomeProtocol {
    func doSomething()
}

在輔助類中,我有一個協議變量的引用:

class someClass {
    var delegate: SomeProtocol? 
}

因為SomeProtocol沒有標記為: class ,所以假設delegate可以是任何東西,在值類型(結構和枚舉)的情況下,不需要weak var變量因為值類型不能創建強引用。 事實上,編譯器不允許除類類型之外的任何weak var

但是,沒有什么能阻止您將類設置為委托,並且如果協議未標記為: class (如SomeProtocol is),則不能使用weak var`並創建保留周期。

class MyClass: NSObject, SomeProtocol {
    func doSomething() { }
}

struct MyStruct: SomeProtocol {
    func doSomething() { }
}

let someClass = SomeClass()
let myStruct = MyStruct()
someClass.delegate = myStruct 
// After myStruct gets assigned to the delegate, do the delegate and the struct refer to the same instance or does the struct get copied?D

let myClass = MyClass()
someClass.delegate = myClass // can't use weak var so myClass is retained

鑒於上面的例子,在使用委托和數據源的情況下,不應該: class總是被使用? 基本上任何用於維護引用的協議都應該始終限制為類對象嗎?

對。 如果你試圖用弱引用來破壞保留周期,你必須使用類,因為weak修飾符只適用於引用類型(類)。

: class大多數時候, : class是首選方法。 但是,作為替代答案,您可以在父對象的deinit方法中設置delegate = nil

例如,假設父對象是具有SomeClass屬性的NSOperation子類,並且此屬性具有實現SomeProtocol的委托:

protocol SomeProtocol {
    func doSomething()
}

class SomeClass {
    var delegate: SomeProtocol?
}

class CustomOperation: NSOperation {
    let foo: SomeClass
}

我們將創建一個實現協議的類:

class SomeProtocolImplementation: SomeProtocol {
    func doSomething() {
        print("Hi!")
    }
}

現在我們可以在init()分配foo

class CustomOperation: NSOperation {
    let foo: SomeClass

    override init() {
        foo = SomeClass()
        foo.delegate = SomeProtocolImplementation()
        super.init()
    }
}

這會創建一個保留周期。 但是,請考慮這種deinit方法:

    deinit {
        foo.delegate = nil
    }

現在,每當CustomOperation將被釋放, foo.delegate將被設置為nil ,打破保留周期。 然后,當自動釋放池在運行循環結束時耗盡時, SomeClassSomeProtocolImplementation都將被釋放。

暫無
暫無

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

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