Протоколы: почему @ObjC требуется для проверки соответствия и необязательных требований?
Свифт документация говорит следующее опротоколы:
Вы можете проверить соответствие протокола только в том случае, если ваш протокол помечен атрибутом @objc, как показано выше для протокола HasArea. Этот атрибут указывает, что протокол должен быть открыт для кода Objective C и описан в Использовании Swift с Какао и Objective C. Даже если вы не взаимодействуете с Objective-C, вам нужно пометить свои протоколы атрибутом @objc, если вы хотите иметь возможность проверки соответствия протокола.
Также обратите внимание, что протоколы @objc могут быть приняты только классами, а не структурами или перечислениями. Если вы пометите свой протокол как @objc для проверки соответствия, вы сможете применять этот протокол только к типам классов.
а также
Необязательные требования к протоколу могут быть указаны, только если ваш протокол помечен атрибутом @objc. Даже если вы не взаимодействуете с Objective-C, вам нужно пометить свои протоколы атрибутом @objc, если вы хотите указать дополнительные требования.
Также обратите внимание, что протоколы @objc могут быть приняты только классами, а не структурами или перечислениями. Если вы пометите свой протокол как @objc, чтобы указать необязательные требования, вы сможете применять этот протокол только к типам классов.
Почему не можешьчистые протоколы Swift (не@objc
) быть проверенным на соответствие. Почему у них нет дополнительных требований? Кто-нибудь может угадать основную причину языкового дизайна?
Я ожидаю, что в какое-то неопределенное (вероятно, далекое) время в будущем Apple будет медленно переопределять и заменятьКакао а такжеCocoaTouch с библиотеками, запрограммированными исключительно в Swift. В то время, если мы не хотим избегать использования каких-либо вещей, связанных с Obj-C, следует ли нам избегать использования необязательных требований к протоколу и проверки соответствия протокола в нашем коде?
Если да, то каков идиоматический способ Swift для достижения аналогичных паттернов без использования@objc
? (Например, делегат с дополнительными методами.)
Например, этот простой вариант использования не может быть реализован с@objc
протоколы (иPrintable
, DebugPrintable
а такжеStreamable
не являются@objc
:
import UIKit
let firstName = "John"
let lastName = "Appleseed"
let age = 33
let height = 1.74
let values: [Any] = [firstName, lastName, age, height]
let stringifiedValues = [String]()
for value in values
{
if let pritanbleValue = value as? Printable
{
stringifiedValues.append(value.description)
}
else if let debugPrintableValue = value as? DebugPrintable
{
stringifiedValues.append(value.debugDescription)
}
else if let streamableValue = value as? Streamable
{
var string = ""
streamableValue.writeTo(&string)
stringifiedValues.append(string)
}
// etc.
else
{
stringifiedValues.append("[NoStringRepresentation]")
}
}