当我在Swift中将变量声明为weak
时,我有时会收到来自Xcode的错误消息:
'弱'可能只适用于类和类绑定协议类型
我只是想知道为什么关键字weak
只能应用于类和类绑定协议类型?它背后的原因是什么?
答案 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)
我在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)
“弱”可以应用从类或类绑定协议类型继承的任何东西
NSObjectProtocol:
协议ViewControllerDelegate:NSObjectProtocol { func getInformation(value:String?)}