Когда использовать @objc в быстром коде?
Я новичок в Swift, и я вижу некоторые методы, такие как:
@objc private func doubleTapGestureRecognized(recognizer: UITapGestureRecognizer)
Мне было интересно, когда использовать @objc? Я прочитал некоторые документы, но они говорят, что если вы хотите, чтобы он вызывался в Objective-C, вы должны добавить флаг @objc
Тем не менее, это частная функция в swift, что делает @obj?
5 ответов
Частный означает, что это видно только в Swift. так что используйте @objc для отображения в Objective-C. Если у вас есть функция для выбора частного функции в swift, это необходимо.
Атрибут @objc делает ваш Swift API доступным в Objective-C и Objective-C.
Еще один поздний ответ, но ни один из существующих ответов на этот вопрос действительно не отвечает на вопрос ОП, а именно: зачем, черт возьми, вам понадобиться @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, у него нет селектора. Поэтому, даже если метод является закрытым и не должен вызываться произвольным внешним кодом, ему потребуется @objc
для того, чтобы DistributedNotification
код, который написан в Objective-C, чтобы иметь возможность вызывать его через его селектор.
Еще один распространенный случай, когда @objc
необходимо поддерживать Key-Value Coding (KVC), особенно в macOS, где KVC и KVO используются для реализации привязки какао. KVC, как и многие другие системы в Какао, реализован в 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 - в противном случае нам пришлось бы написать код для ручной отправки уведомлений в закрытое свойство. willSet
а также didSet
обработчики. Кроме того, статическое свойство, которое сообщает системе KVC, что dependentProperty
зависит от originalProperty
Нужно подвергнуть Objective-C, чтобы система KVC и нашла ее, и позвонила, но это не относится к клиентам нашего кода.
Кроме того, контроллер представления в приложении macOS, который обновляет элементы управления в своем представлении, используя привязки Какао в качестве детали реализации, может сделать определенные частные свойства KVC-совместимыми, чтобы привязать эти элементы управления к ним.
Итак, как вы видите, бывают ситуации, когда метод или свойство, возможно, должны быть доступны Objective-C для взаимодействия с фреймворками, без необходимости быть видимыми для клиентов вашего кода.
@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.
@objc - это атрибут класса, поэтому вы используете
@objc public class MyClass
Он предоставляет методы классов классам Objective C, поэтому вы будете использовать его, только если ваш класс содержит публичные функции
Поздний ответ, но это @objc
поведение немного меняется по сравнению со Swift 4 (который появился в Xcode 9, который был выпущен 10 дней назад).
В Swift 4 некоторые случаи вывода @objc
удалены. Это просто означает, что в некоторых дополнительных случаях, когда до @objc
заголовок был выведен компилятором Swift, он в Swift 4 не выведен.
Читайте больше в предложении Swift Evolution об этом изменении
Как уже упоминалось, в целом @objc
состоит в том, чтобы представить определенные методы среде выполнения Objective C, которая является частью функциональной совместимости Swift с языком.
@objc
представляет декларацию Objective-C runtime
. Давайте посмотрим на#selector
функция Swift для использования среды выполнения Objective-C. В этом случае вы можете определить свой Swift@objc private func
[Больше]
Чтобы использовать функции Swift из Objective-C:
- Класс Swift должен быть расширен с
NSObject
Марка Свифта:
а.
@objcMembers
только класс - выставить всеpublic
конструкторы, поля и методы. Также это применимо для подклассовб.
@objc
класс / перечисление / протокол (кроме структуры) [Именованный тип]@objc
class(необязательно) - выставить значение по умолчаниюpublic init()
. Или@objc(<custom_name>)
чтобы настроить собственное имя для класса.@objc
конструкторы, поля и методы - чтобы выставлять их выборочно
Метод Swift будет доступен под следующим наименованием:
<swiftName>With<firstArgument>:<secondArgument>:
Например:
public func printHelloWorld(arg1: String, arg2:String)
//is reached through:
[someObject printHelloWorldWithArg1: arg2:];
По умолчанию Swift
генерирует код, который доступен только для других Swift
код, но если вам нужно взаимодействовать с Objective-C
время выполнения - все UIKit, например - вам нужно сказать Swift, что делать. Swift
не делает свой код доступным для Objective-C
по умолчанию, чтобы избежать увеличения размера кода.
Если вы просто хотите предоставить один метод или свойство, вы можете пометить этот метод, используя @objc
приписывать. Однако, если вы хотите, чтобы все методы в классе подвергались воздействию Objective-C
Вы можете использовать ярлык: @objcMembers
ключевое слово.
Это полезно, например, когда вы работаете над Swift
язык, и вы хотите использовать рамки из Objective-C
код.
Чтобы использовать функции Swift из Objective-C:
- Класс Свифта должен быть расширен от
NSObject
Марк Свифт:
а.
@objcMembers
класс - разоблачить всеpublic
fields
а такжеmethods
б.
@objc
класс - разоблачитьpublic init()
, Конкретный@objc
public
fields
а такжеmethods
- выставлять их выборочноМетод Свифта будет доступен по следующим именам:
<swiftName>With<firstArgument>:<secondArgument>:
Например:
public func printHelloWorld(arg1: String, arg2:String)
достигается через:[someObject printHelloWorldWithArg1: arg2:];
Узнайте больше здесь