Dans Swift, je vois quelques méthodes comme:
@objc private func doubleTapGestureRecognized(recognizer: UITapGestureRecognizer)
Je me demandais quand utiliser @objc? J'ai lu certains documents, mais ils disent que lorsque vous voulez qu'il soit appelable en Objective-C, vous devez ajouter le drapeau @objc
Cependant, il s'agit d'une fonction privée dans Swift, que fait le @obj?
Réponses:
privé signifie qu'il n'est visible que dans Swift. utilisez donc @objc pour être visible dans Objective-C. Si vous avez une fonction pour sélectionner une fonction privée dans swift, elle est obligatoire.
Voir: 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
la source
@objc private func doubleTapGestureRecognized
, quel est l'intérêt d'avoir à la fois @objc et privé? Êtes-vous en train de dire que les classes Objective-C peuvent écraser doubleTapGestureRecognized?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 unprivate
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 leDistributedNotification
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.
la source
@objc / dynamique
C'est pour la compatibilité: une fois que vous avez importé votre fichier / code Swift dans un projet basé sur Objective-C.
Et utilisez-le si vous voulez que votre propriété / méthode soit accessible par le code ou la classe Objective-C.
La plupart du temps, cela se produit lorsque vous sous-classez une classe Swift de la classe de base Objective-C.
Voici la documentation Apple qui parle de
@objc
.Utilisation de Swift depuis Objective-C
Compatibilité d'interopérabilité linguistique
Liens mis à jour: il
semble que les liens ont été mis à jour par Apple.
la source
@objc est un attribut de classe, vous utilisez donc
@objc public class MyClass
Il expose les méthodes de la classe aux classes Objective C, vous ne l'utiliserez donc que si votre classe contient des fonctions publiques
la source
Une réponse tardive, mais ce
@objc
comportement est en train de changer légèrement à partir de Swift 4 (qui est sorti dans Xcode 9, qui était généralement publié il y a 10 jours).Dans Swift 4, certains cas d'inférence de
@objc
sont supprimés. Cela signifie simplement que dans certains cas supplémentaires où avant que l'en-@objc
tête ait été déduit par le compilateur Swift, il n'est pas déduit dans Swift 4.En savoir plus sur la proposition d'évolution Swift sur ce changement
Comme cela a été mentionné, en général
@objc
est d'exposer certaines méthodes au runtime Objective-C, qui fait partie de l'interopérabilité de Swift avec le langage.la source
@objc
@objc
expose une déclaration àObjective-C runtime
. Jetons un coup d'œil à la#selector
fonctionnalité de Swift pour utiliser un runtime Objective-C. Dans ce cas, vous pouvez définir votre Swift@objc private func
[Plus]Pour utiliser les fonctions de Swift depuis Objective-C:
NSObject
Mark Swift's:
une.
@objcMembers
classe uniquement - pour exposer tous lespublic
constructeurs , champs et méthodes . Il est également applicable pour les sous-classesb.
@objc
class / enum / protocol (sauf struct ) [Type nommé]@objc
class (facultatif) - pour exposer une valeur par défautpublic init()
. Ou@objc(<custom_name>)
pour configurer un nom personnalisé pour la classe.@objc
constructeurs , champs et méthodes - pour les exposer de manière sélectiveLa méthode de Swift sera disponible par le prochain nom:
<swiftName>With<firstArgument>:<secondArgument>:
Par exemple:
public func printHelloWorld(arg1: String, arg2:String) //is reached through: [someObject printHelloWorldWithArg1: arg2:];
[
@objc
etdynamic
]la source