2

假设我们有一个协议

protocol MyProtocol {
    fun someFunc()
}

class AClass {
    var delegate: MyProtocol?
}

AClass 不关心委托是类还是结构。我想要的是有时委托可以是一个类,有时它可以分配给一个结构。

我的问题是我是否应该让代表变得“弱”。

如果是这样,我必须使 MyProtocol 成为“类协议”,以便委托只能是一个类。如果没有,当我将委托分配给班级时,如何避免保留周期?

感谢您的任何提示!

4

2 回答 2

3

应该使代表“弱”

答案是,如果MyProtocol不限于类,你不能让它变得弱,编译器不会让你这样做。

上面的原因是structs 是值类型。没有可以强或弱的引用,因为从逻辑上讲,当您分配委托时,整个结构都会被复制。

如何避免保留周期?

这意味着您必须小心您的委托不包含对类实例的强引用。所以,例如

struct ConcreteDelegate: MyProtocol
{
    fun someFunc() {}
    var instance: AClass

    init()
    {
        instance = AClass()
        instance.delegate = self
    }
}

导致引用循环。它可以通过声明instance

    weak var instance: AClass! 

或者,一个更好的解决方案(IMO),您的协议函数可以将实例作为参数传递,因此委托永远不需要存储对实例的引用。

protocol MyProtocol {
    func someFunc(caller: AClass)
}

您会在很多地方看到 Cocoa 中采用的上述方法,例如表视图数据源协议。

于 2017-10-27T15:38:39.807 回答
0

我认为您忘记了struct不是引用类型而是值类型。这意味着一个类在内存堆中有一个引用,但结构,枚举没有。记住这个事实,weak如果你的协议的委托是 a就没有任何意义,struct因为它不会导致保留循环。

当您只使用类时,您需要担心保留周期。如果你的协议委托是一个类 putweak如果你认为你的类有你的协议的引用并且你的协议可以有你的类的引用 putweak这就是保留周期。

如果您想在deinit测试时检查它的 put 函数,并查看您的类是否正确 deinit 并且没有保存在内存中。基本上就是我知道的,希望对你有帮助。

于 2017-10-27T15:07:38.867 回答