Подтвердить что ты не робот

Быстрый "слабый" протокол не может применяться к классу неклассов

Я немного смущен. Какая разница между protocol A : class { ... } и protocol A{ ... }, и какой из них мы должны использовать в swift?

PS: мы получили ошибку, когда мы писали так:

protocol A{ ... }

weak var delegate: A

ошибка: "слабый" не может применяться к типу неклассов

4b9b3361

Ответ 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.

Поэтому, как правило, вы определяете протокол только для класса, если вам нужно, чтобы типы, принимающие протокол, были ссылочными типами, а не типами значений.

Ответ 2

Вы можете сделать протокол производным от любого типа класса, такого как NSObject или AnyObject. например:

protocol TopNewsTableDelegate  : AnyObject{
  func topNewsTableDidLoadedStories()
}

Ответ 3

Или вы можете напечатать как это

@objc protocol A { ... }

тогда вы можете сделать слабую ссылку делегата