繁体   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