让我们假设我们有一个协议
protocol MyProtocol {
fun someFunc()
}
class AClass {
var delegate: MyProtocol?
}
如果委托是类或结构,则AClass并不关心。我想要的是有时委托可以是一个类,有时它可以分配给一个结构。
我的问题是,我是否应该让代表成为"弱"。
如果是这样,我必须使MyProtocol成为一个"类协议"所以代表必须只是一个班级。 如果没有,当我将委托分配给类时,如何避免保留循环?
感谢任何提示!
答案 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
函数,看看你的类是否正确地被删除而不是保存在内存中。
这基本上就是我所希望的,它会帮助你。