为了账号安全,请及时绑定邮箱和手机立即绑定

如何在“纯” Swift中创建弱协议引用(不带@objc)

如何在“纯” Swift中创建弱协议引用(不带@objc)

达令说 2019-11-21 12:53:14
weak除非a protocol声明为@objc,否则引用似乎在Swift中不起作用,我不希望在纯Swift应用程序中使用它。这段代码给出了一个编译错误(weak不能应用于非类类型MyClassDelegate):class MyClass {  weak var delegate: MyClassDelegate?}protocol MyClassDelegate {}我需要给协议加上前缀@objc,然后它才能工作。问题:什么是完成Swift的“纯” Swift方法weak delegate?
查看完整描述

3 回答

?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

您需要将协议类型声明为class。


protocol ProtocolNameDelegate: class {

    // Protocol stuff goes here

}


class SomeClass {

    weak var delegate: ProtocolNameDelegate?

}

我的理解是,使用class,您可以确保仅在类上使用此协议,而不会在枚举或结构之类的其他东西上使用。


查看完整回答
反对 回复 2019-11-21
?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

补充答案

我一直对代表是否应该软弱感到困惑。最近,我了解了有关委托的详细信息以及何时使用弱引用,因此为了将来的读者,让我在此处添加一些补充要点。


使用weak关键字的目的是避免强参考循环(保留循环)。当两个类实例相互具有强引用时,就会发生强引用循环。他们的参考计数永远不会为零,所以他们永远不会被释放。


weak如果委托是一个类,则仅需要使用。Swift结构和枚举是值类型(在创建新实例时会复制它们的值),而不是引用类型,因此它们不会构成强引用周期。


weak引用始终是可选的(否则,您将使用unowned),并且始终使用var(非let),以便可以在nil取消分配可选项时将其设置为。


父类自然应该对其子类有强烈的引用,因此不要使用weak关键字。但是,当孩子想要引用其父母时,应通过使用weak关键字使其成为弱引用。


weak当您想要引用一个您不拥有的类时,应该使用,而不是仅用于引用其父类的孩子。当两个非层次类需要相互引用时,请选择一个弱类。您选择的一种取决于情况。有关更多信息,请参见此问题的答案。


通常,应将委托人标记为,weak因为大多数委托人都在引用他们不拥有的类。当孩子使用委托与父母沟通时,这绝对是正确的。文档建议使用弱引用作为委托。(但是看这个,太)。


协议可用于引用类型(类)和值类型(结构,枚举)。因此,在可能需要弱化委托的情况下,必须使其成为仅对象协议。做到这一点的方法是添加AnyObject到协议的继承列表中。(过去您是使用class关键字来完成此操作的,但AnyObject现在是首选。)


protocol MyClassDelegate: AnyObject {

    // ...

}


class SomeClass {

    weak var delegate: MyClassDelegate?

}

进一步研究

阅读以下文章有助于我更好地理解这一点。他们还讨论了相关问题,例如unowned关键字和闭包发生的强大参考周期。


查看完整回答
反对 回复 2019-11-21
  • 3 回答
  • 0 关注
  • 560 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信