hnh*_*hnh 553 delegates swift swift-protocols
weak引用似乎在Swift中不起作用,除非a protocol声明为@objc,我不想在纯粹的Swift应用程序中.
此代码给出了编译错误(weak不能应用于非类类型MyClassDelegate):
class MyClass {
weak var delegate: MyClassDelegate?
}
protocol MyClassDelegate {
}
Run Code Online (Sandbox Code Playgroud)
我需要为协议添加前缀@objc,然后才能工作.
问题:什么是"纯粹的"Swift方式来实现weak delegate?
fla*_*nez 1019
您需要将协议类型声明为class.
protocol ProtocolNameDelegate: class {
// Protocol stuff goes here
}
class SomeClass {
weak var delegate: ProtocolNameDelegate?
}
Run Code Online (Sandbox Code Playgroud)
我的理解是使用class,你保证这个协议只用于类,而不是其他东西,如枚举或结构.
Sur*_*gch 272
我一直很困惑代表们是否应该是弱者.最近我学到了更多关于代表以及何时使用弱引用的知识,所以让我在这里为了未来的观众添加一些补充点.
使用weak关键字的目的是避免强引用周期(保留周期).当两个类实例具有相互强引用时,就会发生强引用循环.他们的引用计数永远不会变为零,因此它们永远不会被释放.
weak如果委托是一个类,您只需要使用.Swift结构和枚举是值类型(它们的值在创建新实例时被复制),而不是引用类型,因此它们不会产生强引用循环.
weak引用始终是可选的(否则您将使用unowned)并始终使用var(不let),以便可选的可以在nil取消分配时设置.
父类应该自然地具有对其子类的强引用,因此不使用该weak关键字.但是,当孩子想要引用它的父级时,它应该通过使用weak关键字使其成为弱引用.
weak当您想要引用您不拥有的类时,应该使用它,而不仅仅是引用其父级的子类.当两个非等级类需要相互引用时,选择一个为弱.你选择的那个取决于具体情况.有关此问题的更多信息,请参阅此问题的答案.
作为一般规则,应将委托标记为,weak因为大多数委托都引用了他们不拥有的类.当孩子使用委托与父母沟通时,这肯定是正确的.但是,仍有一些情况下代表可以而且应该使用强引用.
协议可用于引用类型(类)和值类型(结构,枚举).因此,在您需要使委托变弱的情况下,您必须将AnyObject关键字添加到协议中,以便它知道它仅用于引用类型.
protocol MyClassDelegate: AnyObject {
// ...
}
class SomeClass {
weak var delegate: MyClassDelegate?
}
Run Code Online (Sandbox Code Playgroud)阅读以下文章有助于我更好地理解这一点.他们还讨论了相关问题,如class关键字和闭包发生的强引用周期.
Tim*_*hen 36
AnyObject 是在Swift中使用弱引用的官方方法.
class MyClass {
weak var delegate: MyClassDelegate?
}
protocol MyClassDelegate: AnyObject {
}
Run Code Online (Sandbox Code Playgroud)
来自Apple:
为了防止强引用循环,应将委托声明为弱引用.有关弱引用的详细信息,请参阅类实例之间的强引用循环.将协议标记为仅限类将稍后允许您声明委托必须使用弱引用.您通过继承AnyObject将协议标记为仅仅类,如"仅类协议"中所述.
更新: 看起来手册已更新,我所指的示例已被删除.请参阅上面@ @ flainez的回复编辑.
原文: 即使你没有与Obj-C互操作,使用@objc也是正确的方法.它确保您的协议应用于类而不是枚举或结构.请参阅手册中的"检查协议一致性".
| 归档时间: |
|
| 查看次数: |
105381 次 |
| 最近记录: |