如何在'纯粹的'Swift(w / o @objc)中创build一个弱协议引用
weak
引用似乎没有在Swift中工作,除非一个protocol
被声明为@objc
,我不想在一个纯粹的Swift应用程序。
此代码给出了编译错误( weak
不能应用于非types的MyClassDelegate
):
class MyClass { weak var delegate: MyClassDelegate? } protocol MyClassDelegate { }
我需要以@objc
作为前缀,然后才能正常工作。
问:什么是“纯粹”的快速完成weak
delegate
?
您需要将协议的types声明为class
。
protocol ProtocolNameDelegate: class { // Protocol stuff goes here } class SomeClass { weak var delegate: ProtocolNameDelegate? }
我的理解是,使用class
,你保证这个协议将只用于类,没有其他东西像枚举或结构。
补充答案
我一直对代表是否应该软弱感到困惑。 最近我已经学到了更多关于代表和什么时候使用弱引用的内容,所以为了未来的观众,我在这里补充一些补充点。
-
使用
weak
关键字的目的是为了避免强参考周期(保留周期)。 当两个类实例具有强相互引用时,强引用周期发生。 他们的引用计数永远不会归零,所以他们永远不会被释放。 -
如果委托是一个类,则只需使用
weak
。 Swift结构和枚举是值types(它们的值在新实例制作时被复制),而不是引用types,所以它们不会产生强的引用周期。 -
weak
引用总是可选的(否则你将使用unowned
),并总是使用var
(let
),以便可选项可以设置nil
时,它被释放。 -
一个父类自然应该有一个强types的子类,因此不使用
weak
关键字。 当一个孩子想要引用它的父母时,应该使用weak
关键字来使它成为一个弱引用。 -
当你想引用一个你不拥有的类时,应该使用
weak
,而不仅仅是引用其父类的子类。 当两个非层次类需要相互引用时,select一个弱。 你select的取决于情况。 请参阅此问题的答案以了解更多信息。 -
作为一般规则,代表应该被标记为
weak
因为大多数代表正在引用他们不拥有的类。 当孩子使用委托与父母沟通时,这当然是正确的。 但是,在某些情况下 ,代表可以并应该使用强有力的参考。 -
协议可以用于引用types(类)和非引用types(结构体,枚举)。 因此,在需要使委托变弱的可能情况下,您必须将
class
关键字添加到协议中,以便它知道仅用于引用types。protocol MyClassDelegate: class { // ... } class SomeClass { weak var delegate: MyClassDelegate? }
进一步研究
阅读以下文章是帮助我更好地理解这一点的。 他们还讨论相关的问题,如unowned
关键字和强大的引用周期发生在closures。
- Swift文档: 自动引用计数
- “弱,强,无主,我的!” – Swift参考指南
- 强,弱,无主 – sortingARC和Swift
有关
- 如何在Swift中创build代表
- iOS:如何在Swift中制作弱代表
- Swift委托 – 何时在委托上使用弱指针
更新:它看起来像手册已经更新,我所指的例子已被删除。 请参阅上面编辑@ flainez的回答。
原文:即使您不与Obj-C互操作,使用@objc也是正确的做法。 它确保你的协议被应用到一个类,而不是一个枚举或结构。 请参阅手册中的“检查协议一致性”。
苹果使用“NSObjectProtocol”而不是“class”。
public protocol UIScrollViewDelegate : NSObjectProtocol { ... }
这也适用于我,并删除我试图实现我自己的委托模式时看到的错误。