僅限類的協議
協議可以指定只有一個類可以通過在其繼承列表中使用 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?