在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允许您以这种方式射击自己的脚这一事实似乎违反了其安全性设计理念。
需要两个保留周期...
如果您真的想用这种方法,那么为什么不忽略weak
并使其成为一个有力的参考。如果委托还对要委派的对象保持强烈的引用,您将只有一个问题。
因此,委派的职责是确保任何相互引用都是弱引用,由于MyClass
是一个类,因此在任何时候都应该是可能的,因此您始终可以对其声明弱引用。
如果您确实想在类或结构上支持协议,则始终可以将委托存储在单独的基础变量中。这样,当委托是一个类时,您可能会遇到一个弱点。遵循以下内容:
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)")