弱引用似乎在Swift中不起作用,除非协议声明为@objc,这是我不希望在纯Swift应用程序中使用的。
这段代码给出了一个编译错误(weak不能应用于非类类型MyClassDelegate):
class MyClass {
weak var delegate: MyClassDelegate?
}
protocol MyClassDelegate {
}
我需要用@objc作为协议的前缀,然后它就可以工作了。
问:完成弱委托的“纯”Swift方式是什么?
弱引用似乎在Swift中不起作用,除非协议声明为@objc,这是我不希望在纯Swift应用程序中使用的。
这段代码给出了一个编译错误(weak不能应用于非类类型MyClassDelegate):
class MyClass {
weak var delegate: MyClassDelegate?
}
protocol MyClassDelegate {
}
我需要用@objc作为协议的前缀,然后它就可以工作了。
问:完成弱委托的“纯”Swift方式是什么?
当前回答
您需要将协议的类型声明为AnyObject。
protocol ProtocolNameDelegate: AnyObject {
// Protocol stuff goes here
}
class SomeClass {
weak var delegate: ProtocolNameDelegate?
}
使用AnyObject,你说只有类可以符合这个协议,而结构或枚举不能。
其他回答
AnyObject是Swift中使用弱引用的官方方式。
class MyClass {
weak var delegate: MyClassDelegate?
}
protocol MyClassDelegate: AnyObject {
}
从苹果公司:
为了防止强引用循环,委托应该声明为 弱引用。有关弱引用的详细信息,请参见 类实例之间的强引用循环。标记协议 As -only稍后将允许您声明委托必须 使用弱引用。将协议标记为仅类 从AnyObject继承,如仅类协议中所述。
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html#//apple_ref/doc/uid/TP40014097-CH25-ID276
protocol MyProtocol {
func doSomething()
}
class MyClass: MyProtocol {
func doSomething() {
print("Doing something")
}
}
var weakProtocol: Weak<MyProtocol>?
let myObject = MyClass()
weakProtocol = Weak(myObject)
weakProtocol?.doSomething() // Will print "Doing something"
苹果使用“NSObjectProtocol”而不是“class”。
public protocol UIScrollViewDelegate : NSObjectProtocol {
...
}
这也适用于我,并删除了我在尝试实现自己的委托模式时所看到的错误。
弱限定符仅适用于引用对象。除非在协议上添加@objc、AnyObject或类限定符,否则符合协议的对象可能不是引用对象。
因此,您需要这些限定符中的一个(建议使用AnyObject,因为预计不推荐使用class)。
顺便说一下,请注意,在你的类和属性中添加@objc有时是必需的,即使在“纯Swift”应用程序中也是如此。这与你的开发语言无关。它导致编译器以一种与Objective-C运行时兼容的方式构建代码,这对于某些操作系统接口(例如目标/动作和旧式键路径)是必需的。
protocol必须是AnyObject的子类,class
示例如下
protocol NameOfProtocol: class {
// member of protocol
}
class ClassName: UIViewController {
weak var delegate: NameOfProtocol?
}