协议可以指定只有一个类可以通过使用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?