Ответ 1
protocol A : class { ... }
определяет "протокол только для класса ": только типы классов (а не структуры или перечисления) могут принять этот протокол.
Слабые ссылки определены только для ссылочных типов. Классы являются ссылочными типами, структуры и перечисления являются типами значений. (Замыкания также являются ссылочными типами, но замыкания не могут принять протокол, поэтому они не имеют значения в этом контексте.)
Следовательно, если объект, соответствующий протоколу, должен храниться в слабом свойстве, тогда протокол должен быть протоколом только для класса.
Вот еще один пример, который требует протокол только для класса:
protocol A {
var name : String { get set }
}
func foo(a : A) {
a.name = "bar" // error: cannot assign to property: 'a' is a 'let' constant
}
Это не компилируется, потому что для экземпляров структур и перечислений a.name = "bar"
является мутацией a
. Если вы определяете протокол как
protocol A : class {
var name : String { get set }
}
тогда компилятор знает, что a
является экземпляром типа класса, а a
является ссылкой на хранилище объектов, а a.name = "bar"
изменяет ссылочный объект, но не a
.
Поэтому, как правило, вы определяете протокол только для класса, если вам нужно, чтобы типы, принимающие протокол, были ссылочными типами, а не типами значений.