swift 中对弱委托的困惑

Confusions about weak delegate in swift

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

protocol MyProtocol {
    fun someFunc()
}

class AClass {
    var delegate: MyProtocol?
}

AClass 不关心委托是 class 还是结构。我想要的是有时委托可以是 class 有时可以分配给结构。

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

如果是这样,我必须将 MyProtocol 设置为 "class Protocol",这样委托就只能是 class。 如果不是,当我将委托分配给 class 时,如何避免保留循环?

感谢任何提示!

我想你忘了 struct 不是 引用类型而是值类型 。这意味着 class 在内存堆中有引用,但 结构,枚举没有 。记住这个事实,如果你的协议的委托是 struct,那么放置 weak 是没有意义的,因为 它不会导致保留周期。

当您仅使用 classes 时,您需要担心保留周期。如果你的协议代表是 class put weak 如果你认为你的 class 引用了你的协议并且你的协议可以引用你的 class put weak 这就是保留周期。

如果您想检查它,请在测试时放入 deinit 函数,看看您的 class 是否正确地 deinit 并且没有保存在内存中。 我知道的就这些了希望对你有帮助

should make the delegate to be "weak"

答案是,如果MyProtocol不限制为classes,你不能让它变弱,编译器不会让你。

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

how can I avoid retain cycle?

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

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 的很多地方看到上述方法,例如 table 查看数据源协议。