Swift协议&与类弱的引用

时间:2016-04-24 00:54:34

标签: ios swift

如果我有协议:

protocol SomeProtocol {
    func doSomething()
}

在帮助器类中,我引用了一个协议变量:

class someClass {
    var delegate: SomeProtocol? 
}

因为SomeProtocol未标有: class,所以假设delegate可以是任何内容,而在价值类型(结构和枚举)的情况下,{&1}} #39;不需要weak var,因为值类型无法创建强引用。事实上,除了类类型之外,编译器不允许weak var

但是,没有什么可以阻止您将类设置为代理,并且协议未标记为: class(因为SomeProtocol is),弱变量不能使用,并且创建一个保留周期。

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?基本上任何用于维护引用的协议都应该始终限于类对象吗?

2 个答案:

答案 0 :(得分:1)

右。如果你试图用弱引用来破坏保留周期,你必须使用类,因为weak修饰符仅适用于引用类型(类)。

答案 1 :(得分:0)

: class是大多数时候首选的方法。但是,作为替代答案,您可以在父对象的delegate = nil方法中设置deinit

例如,假设父对象是具有NSOperation属性的SomeClass子类,并且此属性具有实现SomeProtocol的委托:

protocol SomeProtocol {
    func doSomething()
}

class SomeClass {
    var delegate: SomeProtocol?
}

class CustomOperation: NSOperation {
    let foo: SomeClass
}

我们也会创建一个实现协议的类:

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

现在我们可以在foo中分配init()

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都将被释放。