仅限类的协议
协议可以指定只有一个类可以通过在其继承列表中使用 class
关键字来实现它。此关键字必须出现在此列表中的任何其他继承协议之前。
protocol ClassOnlyProtocol: class, SomeOtherProtocol {
// Protocol requirements
}
如果非类类型试图实现 ClassOnlyProtocol
,则将生成编译器错误。
struct MyStruct: ClassOnlyProtocol {
// error: Non-class type 'MyStruct' cannot conform to class protocol 'ClassOnlyProtocol'
}
其他协议可以从 ClassOnlyProtocol
继承,但它们将具有相同的仅类要求。
protocol MyProtocol: ClassOnlyProtocol {
// ClassOnlyProtocol Requirements
// MyProtocol Requirements
}
class MySecondClass: MyProtocol {
// ClassOnlyProtocol Requirements
// MyProtocol Requirements
}
仅类协议的引用语义
当符合类型未知时,使用仅类协议允许引用语义 。
protocol Foo : class {
var bar : String { get set }
}
func takesAFoo(foo:Foo) {
// this assignment requires reference semantics,
// as foo is a let constant in this scope.
foo.bar = "new value"
}
在此示例中,由于 Foo
是仅类协议,因此对于 bar
的赋值是有效的,因为编译器知道 foo
是类类型,因此具有引用语义。
如果 Foo
不是仅限类的协议,则会产生编译器错误 - 因为符合类型可能是值类型 ,这需要 var
注释才能变为可变。
protocol Foo {
var bar : String { get set }
}
func takesAFoo(foo:Foo) {
foo.bar = "new value" // error: Cannot assign to property: 'foo' is a 'let' constant
}
func takesAFoo(foo:Foo) {
var foo = foo // mutable copy of foo
foo.bar = "new value" // no error – satisfies both reference and value semantics
}
协议类型的弱变量
将 weak
修饰符应用于协议类型的变量时,该协议类型必须是仅类的,因为 weak
只能应用于引用类型。
weak var weakReference : ClassOnlyProtocol?