协议可以指定只有一个类可以通过使用class其继承列表中的关键字来实现它。此关键字必须出现在此列表中任何其他继承的协议之前。
protocol ClassOnlyProtocol: class, SomeOtherProtocol {
// 协议要求
}如果非类类型尝试实现ClassOnlyProtocol,则会生成编译器错误。
struct MyStruct: ClassOnlyProtocol {
// 错误:非类类型“ MyStruct”不符合类协议“ ClassOnlyProtocol”
}其他协议可能继承自ClassOnlyProtocol,但它们具有相同的仅类要求。
protocol MyProtocol: ClassOnlyProtocol {
// ClassOnlyProtocol要求
// 我的协议要求
}
class MySecondClass: MyProtocol {
// ClassOnlyProtocol要求
// 我的协议要求
}当一致类型未知时,使用仅类协议可以提供参考语义。
protocol Foo : class {
var bar : String { get set }
}
func takesAFoo(foo:Foo) {
// 此分配需要参考语义,
// 因为foo是在此范围内的let常数。
foo.bar= "new value"
}在此示例中,与Foo仅类协议一样,bar由于编译器知道foo类类型,因此对的分配有效,因此具有引用语义。
如果Foo不是仅基于类的协议,则将产生编译器错误-因为符合类型可能是值类型,因此需要var注释才能使其可变。
protocol Foo {
var bar : String { get set }
}
func takesAFoo(foo:Foo) {
foo.bar= "new value" // 错误:无法分配给属性:'foo'是一个'let'常量
}func takesAFoo(foo:Foo) { var foo = foo // foo的可变副本
foo.bar= "new value" // 没有错误-同时满足引用和值语义
}将weak修饰符应用于协议类型的变量时,该协议类型必须是仅类的,因为weak只能应用于引用类型。
weak var weakReference : ClassOnlyProtocol?