为什么关键字"弱"仅适用于类和类绑定协议类型

时间:2016-08-09 02:29:21

标签: swift variables weak-references

当我在Swift中将变量声明为weak时,我有时会收到来自Xcode的错误消息:

  

'弱'可能只适用于类和类绑定协议类型

我只是想知道为什么关键字weak只能应用于类和类绑定协议类型?它背后的原因是什么?

11 个答案:

答案 0 :(得分:121)

此错误的一个常见原因是您已声明自己的协议,但忘记继承NSObjectProtocol:

protocol PenguinDelegate: NSObjectProtocol {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate: PenguinDelegate?
}

如果您忘记继承NSObjectProtocol,上面的代码会给您错误。原因是weak仅对引用类型(类)有意义。因此,通过清楚地声明PenguinDelegate是针对类而不是值类型,使编译器不那么紧张。

答案 1 :(得分:60)

protocol PenguinDelegate: class {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate: PenguinDelegate?
}

如果您在协议之后键入class,它也可以正常工作,对于NSObjectProtocol来说似乎更合适。

答案 2 :(得分:56)

weak是引用类型的限定符(与值类型相反,例如struct和内置值类型)。

引用类型允许您对同一对象进行多次引用。当最后一个强引用停止引用它时,对象将被释放(弱引用不计数)。

另一方面,值类型由副本分配。引用计数不适用,因此weak修饰符对它们没有意义。

答案 3 :(得分:11)

以防其他人认为您的代码中的所有内容都像我一样正确,请检查您是否错误地将:替换为=

这就是我所拥有的。它也给了我同样的错误:

protocol PenguinDelegate: class {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate = PenguinDelegate?
}

但正确的方法是:

protocol PenguinDelegate: class {
    func userDidTapThePenguin()
}

class MyViewController: UIViewController {
    weak var delegate: PenguinDelegate?
}

你看到了区别吗?我花了一段时间才看到我有一个等号而不是冒号。还要注意我确实在同一行中得到了其他错误,因为我认为我的第一个错误似乎最有可能是真正的问题:

  

- weak只能应用于类和类绑定协议类型

: - <

答案 4 :(得分:2)

weak适用于ARC(自动参考计数)。这意味着不添加引用计数。所以它只适用于Class。在Swift中,您将获得安全性的可选值。

答案 5 :(得分:2)

我发现在一个案例中您甚至有类型但仍然收到此错误消息。

例如,

class MyVC: UIViewController {
   var myText: UITextView = {
      [weak self]
      let text = UITextView()
      // some codes using self
      return text
   }()
}

这里从匿名块返回UITextView对象作为var myText的初始化。我得到了相同类型的错误消息。要解决此问题,必须将var标记为lazy

class MyVC: UIViewController {
   lasy var myText: UITextView = {
      [weak self]
      let text = UITextView()
      // some codes using self
      return text
   }()
}

答案 6 :(得分:1)

我试图为闭包捕获String和Array类型的属性。我收到了这些错误:

  

'weak'可能只适用于类和类绑定协议类型,而不适用于'[String]'

     

'weak'可能只适用于类和类绑定协议类型,而不适用于'String'

我在操场上玩了一会儿,事实证明,捕获自我对于这些类型来说已经足够了。

答案 7 :(得分:1)

enter image description here我在swift中使用了客观的C类来实现一个scrollView。我创建了滚动视图的IBOutlet。在编译代码时,此错误开始显示。

因此,要解决此类问题,请在桥接标题中导入该类

  

import" YourClass.h"

我正在使用Xcode 9.2和swift 3.2

答案 8 :(得分:1)

仅供参考,谁没有更新。 在实施了快速提案SE-0156 https://github.com/apple/swift-evolution/blob/master/proposals/0156-subclass-existentials.md之后,Swift文档的“仅类协议”部分https://docs.swift.org/swift-book/LanguageGuide/Protocols.html现在描述为使用AnyObject代替类。 因此,将来有可能不推荐使用:class

答案 9 :(得分:0)

weak仅适用于引用类型,因此,如果您从struct(而不是class)进行调用,则Xcode将报告错误。

答案 10 :(得分:0)

  1. 弱不适用于值类型。
  2. 弱者只出现在班上。

“弱”可以应用从类或类绑定协议类型继承的任何东西

  1. 类协议: 协议ViewControllerDelegate:类{     func getInformationk(value:String?)}
  2. NSObjectProtocol:

    协议ViewControllerDelegate:NSObjectProtocol {     func getInformation(value:String?)}