swift2 Swift委派协议无法防止保留周期问题

qlvxas9a  于 2022-11-06  发布在  Swift
关注(0)|答案(2)|浏览(182)

在Swift中,如果我创建了一个委托协议,它可以通过类和结构来符合。

protocol MyDelegate {
  // Can be conformed to by class or struct
}

这个问题在我声明委托的时候出现了。如果委托是一个类示例,我希望变量是弱的,以避免保留循环。如果它是一个结构体,就没有这样的需要--事实上,Swift不允许我把委托变量设置为弱的。注意:我知道如何创建一个弱委托,但关键问题是-如果您创建一个可以是弱的委托协议,除非您使其仅符合类,否则您无法强制执行保留循环。

class MyClass {
  // Want weak var here to avoid cyclical reference
  // but Swift won't allow it because MyDelegate can be
  // conformed by struct as well.  Dropping weak means
  // cyclical reference cannot be prevented
  weak var delegate: MyDelegate?
}

class MyConformingClass: MyDelegate {

}

or

struct MyConformingStruct: MyDelegate {

}

看起来我们需要声明协议在任何时候都只用于类,因为非常规委托协议不能防止保留循环:

protocol MyDelegate: class {

}

事实上,斯威夫特允许你以这种方式开枪打自己的脚,这似乎违背了它在安全方面的设计理念。

ac1kyiln

ac1kyiln1#

如果你真的想支持类或结构体上的协议,你可以将委托存储在单独的底层变量中。这样,当委托是一个类时,你就可以有一个弱的。如下所示:

protocol MyDelegate {
  // Can be conformed to by class or struct
}

class MyClass {
    private weak var delegateFromClass: AnyObject?
    private var delegateFromStruct: MyDelegate?
    var delegate: MyDelegate? {
        get {
            return (delegateFromClass as? MyDelegate) ?? delegateFromStruct
        }
        set {
            if newValue is AnyObject {
                delegateFromClass = newValue as? AnyObject
                delegateFromStruct = nil
            } else {
                delegateFromClass = nil
                delegateFromStruct = newValue
            }
        }
    }
}

class MyConformingClass: MyDelegate {

}

struct MyConformingStruct: MyDelegate {

}

print(" \(MyConformingClass() is AnyObject) \(MyConformingStruct() is AnyObject)")
aamkag61

aamkag612#

一个保留周期需要两个人...
如果你真的想这样做,为什么不把weak去掉,让它成为一个强引用呢?只有当委托也维护了一个对它所委托的对象的强引用时,你才会有问题。
因此委托的职责是确保任何互逆引用都是弱引用,这在任何时候都是可能的,因为MyClass是一个类,因此你总是可以声明一个对它的弱引用。

相关问题