A protocol may specify that only a class can implement it through using the class
keyword in its inheritance list. This keyword must appear before any other inherited protocols in this list.
protocol ClassOnlyProtocol: class, SomeOtherProtocol {
// Protocol requirements
}
If a non-class type tries to implement ClassOnlyProtocol
, a compiler error will be generated.
struct MyStruct: ClassOnlyProtocol {
// error: Non-class type 'MyStruct' cannot conform to class protocol 'ClassOnlyProtocol'
}
Other protocols may inherit from the ClassOnlyProtocol
, but they will have the same class-only requirement.
protocol MyProtocol: ClassOnlyProtocol {
// ClassOnlyProtocol Requirements
// MyProtocol Requirements
}
class MySecondClass: MyProtocol {
// ClassOnlyProtocol Requirements
// MyProtocol Requirements
}
Using a class-only protocol allows for reference semantics when the conforming type is unknown.
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"
}
In this example, as Foo
is a class-only protocol, the assignment to bar
is valid as the compiler knows that foo
is a class type, and therefore has reference semantics.
If Foo
was not a class-only protocol, a compiler error would be yielded – as the conforming type could be a value type, which would require a var
annotation in order to be mutable.
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
}
When applying the weak
modifier to a variable of protocol type, that protocol type must be class-only, as weak
can only be applied to reference types.
weak var weakReference : ClassOnlyProtocol?