Когда использовать @objc в быстром коде?
Я новичок в быстром, и вижу некоторые методы вроде:
@objc private func doubleTapGestureRecognized(recognizer: UITapGestureRecognizer)
Мне было интересно, когда использовать @objc? Я прочитал несколько документов, но они говорят, что если вы хотите, чтобы он был доступен в Objective-C, вы должны добавить флаг @objc
Однако, это частная функция в swift, что делает @obj?
Ответы
Ответ 1
private означает, что он отображается только в Swift.
поэтому используйте @objc для видимого в Objective-C.
Если у вас есть функция для выбора частной функции в swift, это необходимо.
Атрибут @objc делает ваш Swift API доступным в Objective-C и Objective-C времени выполнения.
См:
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html
Ответ 2
Еще один поздний ответ, но ни один из существующих ответов на этот вопрос действительно не отвечает на вопрос OP, а именно: почему вам нужно использовать @objc
для члена класса private
, если @objc
есть для взаимодействия с Objective-C, и этот вопрос является закрытым, что означает, что даже если у вас есть код Objective-C в вашем проекте, он все равно не сможет видеть участника?
Причина в том, что, поскольку многие из фреймворков написаны в Objective-C, иногда Objective-C нужны функции для взаимодействия с определенными API-интерфейсами.
Например, предположим, что я хочу зарегистрироваться для уведомления через DistributedNotificationCenter
:
DistributedNotificationCenter.default.addObserver(self,
selector: #selector(somethingHappened(_:)),
name: someNotification,
object: nil)
Чтобы это сработало, мы должны иметь возможность получить селектор для метода somethingHappened
. Тем не менее, селектор представляет собой концепцию Objective-C, поэтому, если метод не отображается в Objective-C, у него нет селектора. Поэтому, даже если метод является закрытым и не должен вызываться произвольным внешним кодом, для кода DistributedNotification
, который написан в Objective-C, для него может понадобиться @objc
, чтобы иметь возможность называть его через его селектор.
Другим распространенным случаем, когда требуется @objc
, является поддержка кодирования по ключевым словам (KVC), особенно на macOS, где KVC и KVO используются для реализации привязок Cocoa. KVC, как и многие другие системы в Cocoa, реализован в Objective-C, что приводит к тому, что свойства, совместимые с KVC, будут отображаться во время выполнения Objective-C. Иногда для свойств, совместимых с KVC, имеет смысл быть приватным. Например, когда у вас есть свойство, которое влияет на другие свойства:
@objc private dynamic var originalProperty: String
@objc private static let keyPathsForValuesAffectingDependentProperty: Set<String> = [
#keyPath(originalProperty)
]
@objc public var dependentProperty: String { return changeItSomehow(self.originalProperty) }
В этом случае наше фактическое сохраненное свойство является приватным, но зависимое свойство, которое мы делаем для внешнего кода, должно отправлять свои уведомления при обновлении частного свойства. Пометив частную собственность как @objc
, мы можем легко сделать это, настроив зависимость KVC, иначе нам пришлось бы писать код, чтобы вручную отправлять уведомления в обработчиках private willSet
и didSet
. Кроме того, статическое свойство, информирующее систему KVC о том, что dependentProperty
зависит от originalProperty
, должно подвергаться Objective-C, чтобы система KVC находила ее и называла ее, но она не касалась клиентов нашего кода.
Кроме того, контроллер вида в приложении macOS, который обновляет элементы управления в своем представлении с помощью Cocoa Bindings в качестве детали реализации, может сделать определенные частные свойства KVC-совместимыми, чтобы связать эти элементы управления с ними.
Итак, как вы видите, бывают случаи, когда метод или свойство может быть подвергнут воздействию Objective-C, чтобы взаимодействовать с фреймворками, не обязательно быть видимым для клиентов вашего кода.
Ответ 3
@objc/dynamic
Это для совместимости: как только вы импортируете ваш файл/код Swift в проект на основе Objective-C.
И используйте это, если хотите, чтобы к вашему свойству/методу обращался код или класс Objective-C.
В большинстве случаев это происходит, когда вы подклассифицируете класс Swift базового класса Objective-C.
Класс или протокол Swift должны быть помечены атрибутом @objc, чтобы они были доступны и могли использоваться в Objective-C. Этот атрибут сообщает компилятору, что этот фрагмент кода Swift доступен из Objective-C. Если ваш класс Swift является потомком класса Objective-C, компилятор автоматически добавит для вас атрибут @objc.
Вот яблочная документация, в которой говорится о @objc
.
Использование Swift из Objective-C
Совместимость языков
Обновленные ссылки:
Похоже, что ссылки были обновлены Apple.
Ответ 4
@objc - это атрибут класса, поэтому вы используете
@objc public class MyClass
Он предоставляет методы класса классам Objective C, поэтому вы будете использовать его, только если ваш класс содержит публичные функции
Ответ 5
Поздний ответ, но это поведение @objc
немного меняется по сравнению со Swift 4 (который появился в Xcode 9, который обычно выпускался 10 дней назад).
В Swift 4 некоторые случаи вывода @objc
удалены. Это просто означает, что в некоторых дополнительных случаях, когда заголовок @objc
был выведен компилятором Swift, он в Swift 4 не выводился.
Читайте больше в предложении Swift Evolution об этом изменении
Как уже упоминалось, в общем случае @objc
должен предоставлять определенные методы среде выполнения Objective-C, которая является частью функциональной совместимости Swift языка.
Ответ 6
По умолчанию Swift
генерирует код, который доступен только для другого кода Swift
, но если вам нужно взаимодействовать со средой выполнения Objective-C
- например, со всем UIKit - вам нужно указать Swift, что делать. Swift
не делает свой код доступным для Objective-C
по умолчанию, чтобы избежать увеличения его размера.
Если вы просто хотите предоставить один метод или свойство, вы можете пометить этот метод с помощью атрибута @objc
. Однако, если вы хотите, чтобы все методы в классе были доступны Objective-C
, вы можете использовать ярлык: ключевое слово @objcMembers
.
Это полезно, например, когда вы работаете с фреймворком на языке Swift
и хотите использовать фреймворк из кода Objective-C
.
Чтобы использовать функции Swift из Objective-C:
- Класс Swift должен быть расширен с
NSObject
Марк Свифт:
а. @objcMembers
class - выставить все поля public
fields и методами
б. @objc
class - выставить public init()
.
@objc
public
поля и методы - чтобы выставить их выборочно
Метод Swift будет доступен по следующему имени:
<swiftName>With<firstArgument>:<secondArgument>:
Например: public func printHelloWorld(arg1: String, arg2:String)
достигается через: [someObject printHelloWorldWithArg1: arg2:];
Подробнее здесь, здесь