僅限類的協議

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