web-dev-qa-db-fra.com

Xcode 7.3 / Swift 2: avertissement "Aucune méthode déclarée avec le sélecteur Objective-C")

J'utilise des sélecteurs depuis un certain temps, et même après avoir migré vers Swift, j'ai pu les utiliser sans problèmes. C'est comme cela que j'utilisais sur Swift 2 sans problèmes jusqu'à ce que je mette à jour Xcode vers la version 7.3:

enter image description here

Comme utilisation, je vois des sélecteurs avec NSTimer.

C'est l'action qui s'appelle:

 func Start () {

 }

Comme vous pouvez le constater, Xcode 7.3 génère maintenant un avertissement "Aucune méthode déclarée avec le sélecteur Objective-C". En cliquant sur l'avertissement, Xcode propose une solution rapide au code en ajoutant "Selector", mais je reçois toujours le même avertissement: enter image description here

43
tomDev

Depuis Swift 2.2/Xcode 7.3, il existe un nouveau moyen d’utiliser un sélecteur: Selector("funcName") a été remplacé par #selector(ClassName.funcName)

Jetez un oeil à https://github.com/Apple/Swift-evolution/blob/master/proposals/0022-objc-selectors.md ,

tl; dr;

Remplacez Selector("Start") par #selector(YOUR_CLASS.Start)

où YOUR_CLASS = classe de la cible dans un contexte donné.

Si vous ne voulez pas le faire manuellement, Xcode fournit une solution facile par défaut. Lorsque vous vous trouvez dans la situation suivante, appuyez sur les triangles jaunes (parfois requis pour appuyer/cliquer plusieurs fois),

enter image description here

cela vous donnera une suggestion: enter image description here

Et si vous sélectionnez cette suggestion, le sélecteur sera automatiquement mis à jour: enter image description here

88
ogres

Les deux déclarations suivantes fonctionnent parfaitement. La partie supérieure est principalement utilisée. Cependant, lorsque la méthode de sélection se trouve dans un ViewController différent, l'avertissement du compilateur "Aucune méthode déclarée avec le sélecteur Objective-C 'buttonHandler'" peut se produire.

La deuxième déclaration énumérée ne donne pas cet avertissement.

button.addTarget(parentViewController, action: Selector("buttonHandler:"), forControlEvents: .TouchUpInside)

button.addTarget(parentViewController, action: #selector(MainViewController.buttonHandler), forControlEvents: .TouchUpInside)

Dans le contrôleur de vue cible (MainViewController), vous pouvez définir le module:

func buttonHandler(sender:UIButton!) {
    print ("Pressed")
}
4
Vincent

On Swift 4 J'ai dû ajouter @objc avant la fonction pour supprimer les avertissements.

C’est ainsi que j’appelle la fonction avec NSTimer:

 Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.intro), userInfo: nil, repeats: false)

Voici comment la fonction est déclarée:

     @objc func intro () {

          // do your stuff here         

     }

J'ai également mis à jour le paramétrage à la demande du Xcode:

enter image description here

Plus d'avertissements, tout semble bien fonctionner.

2
tomDev

Certaines de mes propres conclusions pour appuyer ce que Vincent a dit (trop de temps pour être un commentaire direct)

Ce n'est pas nécessairement dans un contrôleur de vue différent, mais juste dans un fichier différent où le format suivant ne fonctionnera pas:

button.addTarget(parentViewController, action: Selector("buttonHandler:"), forControlEvents: .TouchUpInside)

Par exemple, si vous avez une extension dans un fichier séparé, bien que pour le même contrôleur de vue, ce format Selector("buttonHandler:") ne fonctionnera pas.

En outre, lorsque le sélecteur est dans le même fichier et le même VC, le correctif rapide de Xcode vous invite à inclure le constructeur dans le sélecteur, afin que le sélecteur ressemble à ceci:

#selector(MainViewController.buttonHandler(_:))

Cependant ce format ne fonctionne que lorsque le sélecteur est dans le même fichier VC +, s'il se trouve dans un fichier séparé, mais dans le même VC, la méthode recommandée a été gagnée ' t fonctionne, et vous devez utiliser la méthode sans le constructeur

#selector(MainViewController.buttonHandler)

0
EricK