仅限类的协议

协议可以指定只有一个可以通过在其继承列表中使用 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?