关于swift中弱代表的困惑

时间:2017-10-27 14:55:24

标签: swift delegates retain-cycle weak

让我们假设我们有一个协议

protocol MyProtocol {
    fun someFunc()
}

class AClass {
    var delegate: MyProtocol?
}

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

我的问题是,我是否应该让代表成为"弱"。

如果是这样,我必须使MyProtocol成为一个"类协议"所以代表必须只是一个班级。 如果没有,当我将委托分配给类时,如何避免保留循环?

感谢任何提示!

2 个答案:

答案 0 :(得分:2)

  

应该让代表成为"弱"

答案是,如果MyProtocol不限于课程,你就不能让它变弱,编译器不会让你失望。

上述原因是struct是值类型。没有引用可以强或弱,因为在分配委托时逻辑上会复制整个结构。

  

如何避免保留周期?

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

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采用的上述方法,例如使用表格视图数据源协议。

答案 1 :(得分:0)

我认为您忘记struct不是引用类型而是值类型。这意味着类在内存堆中有引用但结构,枚举没有。记住这一事实,如果协议的代表是weak,则struct没有任何意义,因为它不会导致保留周期。

只使用时,您需要担心保留周期。如果您的协议代表是一个类weak,如果您认为您的类具有协议的引用,并且您的协议可以引用您的类,那么weak就是保留周期。

如果你想在检查时检查它是否放置了deinit函数,看看你的类是否正确地被删除而不是保存在内存中。 这基本上就是我所希望的,它会帮助你。