Еще один поздний ответ, но ни один из существующих ответов на этот вопрос на самом деле не отвечает на вопрос 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, у него нет селектора. Следовательно, даже если метод является частным и не должен вызываться произвольным внешним кодом, ему потребуется, @objc
чтобы DistributedNotification
код, написанный на Objective-C, мог вызывать его через свой селектор.
Другой распространенный случай, когда @objc
это необходимо, - это поддержка кодирования ключевого значения (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, чтобы взаимодействовать с фреймворками, без необходимости быть видимыми для клиентов вашего кода.