web-dev-qa-db-fra.com

L'utilisation de l'inférence Swift 3 @objc en mode Swift 4 est obsolète?

Brièvement, lors de l’utilisation de Xcode 9 Beta, j’ai rencontré l’avertissement suivant:

L'utilisation de l'inférence Swift 3 @objc en mode Swift 4 est obsolète. Veuillez adresser les avertissements d'inférence @objc obsolètes, testez votre code avec la journalisation «Utilisation de l'inférence Swift 3 @objc obsolète» activée et désactivez l'inférence Swob 3 @objc. **

Après quelques recherches, je ne sais toujours pas comment résoudre le problème. J'apprécierais beaucoup les conseils sur la façon de résoudre ce problème ainsi qu'une explication de ce qui se passe. 

Mon objectif est de mieux comprendre ce qui se passe avec mon code. 

437
DaleK

Je me suis débarrassé de cet avertissement en modifiant le paramètre de construction "Swift 3 @objc Inference" de mes cibles en "Par défaut". 

 Disable Swift 3 @objc inference in Xcode9

De cet article :

Avant Swift 4, le compilateur mettait certaines déclarations Swift à la disposition automatique d’Objective-C. Par exemple, s'il s'agit d'un sous-groupe de NSObject, le compilateur a créé des points d'entrée Objective-C pour toutes les méthodes de ces classes. Le mécanisme s'appelle inférence @objc.

Dans Swift 4, cette inférence automatique @objc est obsolète car il est coûteux de générer tous ces points d'entrée Objective-C. Lorsque le paramètre "Swift 3 @objc Inference" est réglé sur "On", l'ancien code fonctionne. Cependant, il affichera les avertissements de dépréciation qui doivent être traités. Il est recommandé de "corriger" ces avertissements et de basculer le paramètre sur "Par défaut", qui est la valeur par défaut pour les nouveaux projets Swift.

Veuillez également vous référer à cette proposition Swift pour plus d’informations.

744
Evgenii

- Qu'est-ce que l'inférence @objc? Que se passe-t-il?

Dans Swift 3, le compilateur déduit @objc à un certain nombre d'endroits pour que vous n'ayez pas à le faire. En d'autres termes, il s'assure d'ajouter @objc pour vous!

Dans Swift 4, le compilateur ne le fait plus (autant). Vous devez maintenant ajouter @objc explicitement.

Par défaut, si vous avez un projet antérieur à Swift 4, vous recevrez des avertissements à ce sujet. Dans un projet Swift 4, vous obtiendrez des erreurs de construction. Ceci est contrôlé via le paramètre de construction Swift_SWIFT3_OBJC_INFERENCE. Dans les projets antérieurs à Swift 4, la valeur est On. Je recommanderais de définir ceci sur Default (ou Off), qui est maintenant l'option par défaut sur un nouveau projet. 

Il faudra un certain temps pour tout convertir, mais comme c'est la valeur par défaut pour Swift 4, cela vaut la peine de le faire.

- Comment puis-je arrêter les avertissements/erreurs du compilateur?

Il existe deux façons de convertir votre code afin que le compilateur ne se plaint pas.

L'une consiste à utiliser @objc sur chaque fonction ou variable devant être exposée à l'exécution d'Objective-C:

@objc func foo() {

}

L'autre consiste à utiliser @objcMembers avec une déclaration Class. Cela permet d’ajouter automatiquement @objc à ALL aux fonctions et variables de la classe. C'est un moyen simple, mais qui a un coût. Par exemple, il peut augmenter la taille de votre application en exposant des fonctions qu'il n'était pas nécessaire d'exposer.

@objcMembers class Test {

}

- Qu'est-ce que @objc et pourquoi est-ce nécessaire?

Si vous introduisez de nouvelles méthodes ou variables dans une classe Swift, les marquer comme @objc les expose au runtime Objective-C. Cela est nécessaire lorsque le code Objective-C utilise votre classe Swift ou, si vous utilisez des fonctionnalités de type Objective-C, telles que Selectors. Par exemple, le modèle action-cible: button.addTarget(self, action:#selector(didPressButton), for:.touchUpInside)

- Pourquoi ne pas tout marquer @objc?

Il y a des négatifs qui viennent avec marquer quelque chose comme @objc:

  • Augmentation de la taille binaire de l'application 
  • Pas de surcharge de fonction

Veuillez garder à l'esprit qu'il s'agit d'un résumé de très haut niveau et qu'il est plus compliqué que ce que j'ai écrit. Je recommanderais de lire la proposition actuelle pour plus d'informations.

Sources:

247
kgaidis

Migrator ne peut pas identifier toutes les fonctions qui ont besoin de @objc Inferred Objective-C thunks marqués deprecated pour vous aider à les trouver.
• Construire des avertissements sur les méthodes obsolètes
• Messages de la console lors de l'exécution de thunks obsolètes

 enter image description here

45
Hassan Taleb

J'ai eu cet avertissement avec le paramètre "Swift 3 @objc Inference" = "Par défaut". Ensuite, j'ai réalisé que c'était défini pour le projet - pas pour la cible. Assurez-vous donc que vous avez le paramètre "Par défaut" dans votre cible pour vous débarrasser de l'avertissement.

8
Dmitry

Vous pouvez simplement passer à "default" au lieu de "ON". Semble plus adhérent à la logique Apple.

(mais tous les autres commentaires sur l'utilisation de @obj restent valables.)

8
ingconti

En effet, vous éliminerez ces avertissements en désactivant Swift 3 @objc Inference . Cependant, des problèmes subtils peuvent apparaître. Par exemple, KVO cessera de fonctionner . Ce code a parfaitement fonctionné sous Swift 3:

for (key, value) in jsonDict {
    if self.value(forKey: key) != nil {
        self.setValue(value, forKey: key)
    }
}

Après la migration vers Swift 4 et le réglage par défaut de "Swift 3 @objc Inference", certaines fonctionnalités de mon projet ont cessé de fonctionner . Il m'a fallu du débogage et des recherches pour trouver une solution à ce problème . À ma connaissance, voici les options:

  • Activer "Swift 3 @objc Inference" (ne fonctionne que si vous avez migré un projet existant depuis Swift 3)  enter image description here
  • Marquez les méthodes et propriétés affectées avec @objc  enter image description here
  • Réactivez l'inférence ObjC pour toute la classe en utilisant @objcMembers  enter image description here

Réactiver l'inférence @objc vous laisse avec les avertissements, mais c'est la solution la plus rapide. Notez qu'il n'est disponible que pour les projets migrés à partir d'une version antérieure de Swift . Les deux autres options sont plus fastidieuses et nécessitent un peu de recherche de code et des tests approfondis.

Voir aussi https://github.com/Apple/Swift-evolution/blob/master/proposals/0160-objc-inference.md

7
Karoly Nyisztor

Swift 3 @objc Inference L'utilisation de l'inférence Swift 3 @objc en mode Swift 4 est obsolète. Veuillez adresser les avertissements d'inférence @objc obsolètes, testez votre code avec la journalisation «Utilisation de l'inférence obsolète Swift 3 @objc» activée, puis désactivez l'inférence en modifiant le paramètre de construction «Swift 3 @objc Inference» en «Par défaut» pour «XMLParsingURL» cible.

arrivé au 

  1. La première étape a été mise en construction

  2. Rechercher dans l'établissement d'inférences de paramètres

  3. changer Swift 3 @objc Inference Par défaut

entrez la description de l'image ici

2
Praveen Kumar

Vous pouvez essayer de "pod update" et/ou "flutter clean"

J'ai également défini ce paramètre dans xcode.

Le paramètre d'interface Objective-C est le suivant:

ObjectiveC interface setting

1
wisekiddo

Je suis un développeur iOS occasionnel (bientôt plus), mais je ne pouvais toujours pas trouver le réglage comme indiqué par l'autre réponse (puisque je n'avais pas l'élément Keychain de la réponse,) Je pourrais simplement ajouter cet instantané avec les emplacements en surbrillance sur lesquels vous devrez cliquer et trouver.

  1. Commencez en haut à gauche
  2. Choisissez l'icône du dossier du projet
  3. Choisissez le nom de votre projet principal sous l’icône du dossier du projet.
  4. Choisissez les paramètres de construction sur le côté droit.
  5. Choisissez votre projet sous CIBLES.
  6. Faites défiler très bas (ou recherchez l’inférence de Word dans la zone de recherche )

 Finding the setting

1
raddevus

Tout ce dont vous avez besoin est d’effectuer un test d’attente jusqu’à la fin, puis cliquez sur Paramètre de construction, Recherchez dans l’inférence de paramètres de construction. c'est tout ce que j'ai fait et travaillé parfaitement.

0
Acasey

L'utilisation de l'inférence Swift 3 @objc en mode Swift 4 est obsolète?

utiliser func call @objc 

func call(){

foo()

}

@objc func foo() {

}
0
Puji Wahono

En plus de ce que @wisekiddo a dit, vous pouvez également modifier vos paramètres de construction dans le fichier project.pbxproj en définissant le Swift 3 @obj Inference sur la valeur par défaut, comme Swift_SWIFT3_OBJC_INFERENCE = Default;, pour vos types de construction (c'est-à-dire le débogage et la publication), en particulier si vous venez de autre environnement que Xcode

0
DaveNOTDavid