在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 {
}
Swift允许你以这种方式射击自己的事实似乎违背了其安全设计理念。
答案 0 :(得分:0)
保留周期需要两个......
如果你真的想这样做,那么为什么不省略weak
并让它成为一个强有力的参考。如果委托还保持对其委派的对象的强引用,则只会出现问题。
因此,委托人有责任确保任何互惠引用都是弱的,这应该是MyClass
是一个类的所有时间,因此你总是可以声明对它的弱引用。
答案 1 :(得分:0)
如果您确实希望在类或结构上支持协议,则可以始终将委托存储在单独的基础变量中。这样,当委托是一个类时,你可以有一个弱点。沿着以下几点:
协议MyDelegate { //可以通过类或结构符合 }
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)")