swift协议'weak'不能应用于非类类型

boo*_*oog 38 protocols swift

我有点困惑.protocol A : class { ... }和之间的区别是什么protocol A{ ... },我们应该在swift中使用哪一个?

PS:我们写这样的时候出错了

protocol A{ ... }

weak var delegate: A
Run Code Online (Sandbox Code Playgroud)

错误:'weak'不能应用于非类类型

Mar*_*n R 90

protocol A : class { ... }
Run Code Online (Sandbox Code Playgroud)

定义"仅类协议":只有类类型(而不是结构或枚举)才能采用此协议.

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

因此,如果符合协议的对象需要存储在弱属性中,则协议必须是仅类协议.

这是另一个需要仅类协议的示例:

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

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

这不会编译,因为结构和枚举的实例a.name = "bar"是一个变异a.如果将协议定义为

protocol A : class { 
    var name : String { get set }
}
Run Code Online (Sandbox Code Playgroud)

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

因此,一般情况下,如果需要采用协议的类型作为引用类型而不是值类型,则应定义仅类协议.


Rog*_*ger 12

如果您使用的是Swift 4 及更高版本

protocol A : AnyObject { ... }
Run Code Online (Sandbox Code Playgroud)


小智 7

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

protocol TopNewsTableDelegate : AnyObject {
    func topNewsTableDidLoadedStories()
}
Run Code Online (Sandbox Code Playgroud)