Swift protocol error: 'weak' cannot be applied to non-class type

Swift protocol error: 'weak' cannot be applied to non-class type

协议和 class 绑定协议有什么区别,我们应该在 Swift 中使用哪一个?

protocol A : class { ... }

protocol A { ... }

当协议未定义为 : class 时尝试添加 weak 委托时出现错误:

protocol A { ... }

weak var delegate: A

报错:

'weak' cannot be applied to non-class type

'weak' must not be applied to non-class-bound 'A'; consider adding a protocol conformance that has a class bound

Swift >= 4:

protocol A : AnyObject { ... {

Swift < 4:

protocol A : class { ... }

定义了一个"class-only protocol":只有class类型(而不是结构或枚举)可以采用这个协议。

弱引用仅为引用类型定义。 类 是引用类型,结构和枚举是值类型。 (闭包也是引用类型,但闭包不能采用 一个协议,因此它们在这种情况下无关紧要。)

因此,如果需要将符合协议的对象存储在弱属性中,则该协议必须是class-only协议。

这是另一个需要 class-only 协议的例子:

protocol A { 
    var name : String { get set }
}

func foo(a : A) {
    a.name = "bar" // error: cannot assign to property: 'a' is a 'let' constant
}

这不会编译,因为对于结构和枚举的实例,a.name = "bar"a 的变体。如果你定义 协议为

protocol A : class { 
    var name : String { get set }
}

然后编译器知道 a 是 class 类型的一个实例 a 是对对象存储的引用, a.name = "bar" 修改引用对象,但不修改 a.

所以一般来说,如果需要,您可以定义一个 class-only 协议 采用协议的类型是引用类型而不是值类型。

您可以使协议派生自任何 class 类型,例如 NSObject 或 AnyObject:

protocol TopNewsTableDelegate : AnyObject {
    func topNewsTableDidLoadedStories()
}

或者你可以这样输入

@objc protocol A { ... }

那么你可以做一个弱委托引用

protocol CustomProtocolName : NSObjectProtocol {
  // ...
}

如果您使用 Swift 4 或更高版本,请使用 AnyObject:

protocol A : AnyObject { ... }

像以前一样使用 class 给出警告并修复它:

Using 'class' keyword to define a class-constrained protocol is deprecated; use 'AnyObject' instead

Replace 'class' with 'AnyObject'