Существует ли тип использования селекторов в Swift?
По большей части Swift является большим улучшением по сравнению с Objective-C с точки зрения безопасности типов. Одним вопиющим исключением являются селекторы. В Objective-C использование выражения @selector(notARealSelector:)
даст предупреждение компилятора. Эквивалент Swift, Selector("notARealSelector:")
всегда будет компилироваться, но будет работать во время выполнения.
Существует ли тип использования селекторов в Swift, поэтому я могу работать с API-интерфейсом Objective-C, который их требует?
У меня есть много наблюдателей NSNotification
в моем приложении, и я хочу, чтобы у меня была какая-то проверка времени компиляции, что я не делаю опечатки в своих селекторах.
Изменить: конкретный вариант использования NSNotificationCenter.addObserver
.
Ответы
Ответ 1
Селектора Typesafe были только что выпущены в Xcode 7.3 beta 4:
let sel = #selector(insertSubview(_:aboveSubview:)) // sel has type
Selector
теперь является гражданином первого класса и поставляется с некоторыми хорошими предупреждениями компилятора Swift. При необходимости вы можете передать строку:
let sel = Selector("propertyName")
См. гораздо более полный ответ здесь: @selector() в Swift?
Примечания к выпуску Xcode: http://adcdownload.apple.com/Developer_Tools/Xcode_7.3_beta_4/Xcode_7.3_beta_4_Release_Notes.pdf
Ответ 2
Используйте понятие Swift для опций как:
if let result = object.notARealSelector?(/* args */) {
// Use Result
}
где? использовал следующий notARealSelector
с возвратом false
до if
, когда такого метода не определено в типе object
.
Существует предостережение для дополнительных требований к протоколу:
Дополнительные требования к протоколу могут быть указаны только в том случае, если ваш протокол отмечен с атрибутом @objc. Даже если вы не взаимодействуете с Objective-C, вам нужно пометить свои протоколы атрибутом @objc, если вы хотите указать необязательные требования.
Но так как вы спрашиваете о дополнительных методах в первую очередь, вы должны говорить об этом в контексте Objective-C.
Ответ 3
Вы можете использовать отражение, чтобы получить имена свойств объекта в виде строк, как указано в этом ответе, но это не сделает связь между идентификатором и его имя строки, как @selector
в ObjC. Некоторое творческое использование рефлексии может обойти эту проблему, но вам также может быть полезно записать ошибку.