弱引用似乎在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

更新: 看起来手册已经更新了,我提到的例子已经被删除了。请看上面@flainez的回答。

原: 使用@objc是正确的方法,即使你没有与Obj-C进行互操作。它确保您的协议应用于类,而不是枚举或结构。请参见手册中的“检查协议一致性”。

苹果使用“NSObjectProtocol”而不是“class”。

public protocol UIScrollViewDelegate : NSObjectProtocol {
   ...
}

这也适用于我,并删除了我在尝试实现自己的委托模式时所看到的错误。

protocol必须是AnyObject的子类,class

示例如下

    protocol NameOfProtocol: class {
   // member of protocol
    }
   class ClassName: UIViewController {
      weak var delegate: NameOfProtocol? 
    }
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"