协议和类限定协议有什么区别,在Swift中应该使用哪一个?
protocol A : class { ... }
protocol A { ... }
尝试在未将协议定义为: class
时,添加一个weak
委托时,会出现错误。protocol A { ... }
weak var delegate: A
出现错误:
'weak' 不能应用于非类类型
或者
'weak' 必须不应用于非类约束的 'A'; 考虑添加一个带有类约束的协议一致性
Swift >= 4:
protocol A : AnyObject { ... }
Swift < 4:
protocol A : class { ... }
定义了一个"仅类可遵循协议":只有类类型(而不是结构体或枚举)可以采用此协议。
弱引用仅适用于引用类型。类是引用类型,结构体和枚举是值类型。(闭包也是引用类型,但闭包不能采用协议,所以在这种情况下无关紧要。)
因此,如果遵循该协议的对象需要存储在弱属性中,则该协议必须是仅类可遵循的协议。
这里是另一个需要仅类可遵循协议的示例:
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
是一个类类型的实例,那么它就知道a
是对象存储的引用,而a.name = "bar"
会修改被引用的对象,但不会修改a
本身。
因此,通常情况下,您需要定义一个仅限于类的协议,如果您需要采用该协议的类型为引用类型而不是值类型。
如果您正在使用 Swift 4 或更高版本,请使用 AnyObject
:
protocol A : AnyObject { ... }
之前使用class
定义泛型约束协议会出现警告和建议更正:
使用'class'关键字来定义一个类约束类型的协议已经被弃用,应该使用'AnyObject'代替。
将'class'替换为'AnyObject'
您可以使协议派生自任何类类型,例如NSObject或AnyObject:
protocol TopNewsTableDelegate : AnyObject {
func topNewsTableDidLoadedStories()
}
protocol CustomProtocolName : NSObjectProtocol {
// ...
}
。
@objc protocol A { ... }
'a'是一个'let'常量
。我有点困惑。是什么让a
在这里成为一个常量? - Suragcha
,例如func foo(a : A)
,默认情况下是常量。 - Martin R