Une autre réponse tardive, mais aucune des réponses existantes à cette question ne répond vraiment à la question du PO, à savoir: pourquoi diable auriez-vous besoin d'utiliser @objc
sur un private
membre de la classe, s'il @objc
y a une interaction avec Objective-C, et le membre en question est privé, ce qui signifie que même si vous avez du code Objective-C dans votre projet, il ne devrait pas pouvoir voir le membre de toute façon?
La raison en est que, comme la plupart des frameworks sont écrits en Objective-C, des fonctionnalités Objective-C sont parfois nécessaires pour interagir avec certaines API.
Par exemple, supposons que je souhaite m'inscrire à une notification via DistributedNotificationCenter
:
DistributedNotificationCenter.default.addObserver(self,
selector: #selector(somethingHappened(_:)),
name: someNotification,
object: nil)
Pour que cela fonctionne, nous devons être en mesure d'obtenir le sélecteur de la somethingHappened
méthode. Cependant, les sélecteurs sont un concept Objective-C, donc si la méthode n'est pas visible par Objective-C, elle n'a pas de sélecteur. Par conséquent, même si la méthode est privée et ne doit pas être appelée par du code extérieur arbitraire, elle aura besoin d'un @objc
in order pour que le DistributedNotification
code, qui est écrit en Objective-C, puisse l'appeler via son sélecteur.
Un autre cas courant où il @objc
est nécessaire est de prendre en charge le codage clé-valeur (KVC), en particulier sur macOS, où KVC et KVO sont utilisés pour implémenter les liaisons Cocoa. KVC est, comme beaucoup d'autres systèmes dans Cocoa, implémenté en Objective-C, ce qui a pour effet d'exiger que les propriétés compatibles KVC soient exposées au runtime Objective-C. Parfois, il est logique que les propriétés compatibles KVC soient privées. Un exemple est lorsque vous avez une propriété qui affecte d'autres propriétés:
@objc private dynamic var originalProperty: String
@objc private static let keyPathsForValuesAffectingDependentProperty: Set<String> = [
#keyPath(originalProperty)
]
@objc public var dependentProperty: String { return changeItSomehow(self.originalProperty) }
Dans ce cas, notre propriété réelle stockée est privée, mais la propriété à charge, que nous n'exposons à un code externe, doit envoyer ses notifications lors de la mise à jour de la propriété privée. En marquant la propriété privée comme , nous pouvons facilement le faire en configurant une dépendance KVC - sinon, nous aurions à écrire du code pour envoyer manuellement les notifications dans la propriété privée et les gestionnaires. En outre, la propriété statique qui informe le système KVC qui dépend de doit être exposée à Objective-C afin que le système KVC le trouve et l'appelle, mais ce n'est pas pertinent pour les clients de notre code.@objc
willSet
didSet
dependentProperty
originalProperty
En outre, un contrôleur de vue dans une application macOS qui met à jour les contrôles dans sa vue à l'aide de liaisons Cocoa comme détail d'implémentation peut rendre certaines propriétés privées compatibles KVC afin de leur lier ces contrôles.
Donc, comme vous le voyez, il y a des moments où une méthode ou une propriété peut avoir besoin d'être exposée à Objective-C afin d'interagir avec les frameworks, sans nécessairement avoir besoin d'être visible pour les clients de votre code.