4 votes

Swift 3 : Pourquoi le symbole _ est ajouté avant sender dans les paramètres de l'action ?

Mon Xcode a été récemment mis à jour vers Xcode 8 avec Swift 3. Ce que j'ai remarqué, c'est que lorsque j'attache des actions à ViewController, les fonctions sont générées dans ce style :

@IBAction func methodName(_ sender: UIButton) {

}

Je ne comprends pas quel est le but d'avoir _ là. Quelqu'un peut-il expliquer pourquoi il est là ? Dans la version précédente de Swift 2.2, elle n'existait pas.

Une autre question est que le projet précédent que j'ai réalisé en regardant le tutoriel a migré vers Swift 3, et il y avait une méthode qui ressemblait à ceci :

func toggleButtons(toggle: Bool) {
    yesButton.isUserInteractionEnabled = toggle
    noButton.isUserInteractionEnabled = toggle
}

J'appelais cette méthode comme ceci : toggleButtons(false) ne passe toujours pas le nom de l'argument. Maintenant le migrateur l'a changé comme ci-dessous mais rien n'a été changé dans l'appel de la méthode plus tard dans le code.

func toggleButtons(_ toggle: Bool) {
    yesButton.isUserInteractionEnabled = toggle
    noButton.isUserInteractionEnabled = toggle
}

La situation est-elle différente de celle du cas précédent ?

7voto

rob mayoff Points 124153

Les autres réponses (dont l'une a été supprimée) couvraient ce que la _ signifie : il élimine le mot-clé lorsque vous appelez la méthode.

Cependant, votre question porte spécifiquement sur "l'attachement des actions au ViewController".

Les méthodes qui ont le @IBAction peut être relié à des contrôles dans votre storyboard (ou xib). Cela signifie que le nom de la méthode sera stocké, sous forme de chaîne de caractères, dans le storyboard, et qu'elle sera appelée à l'aide du système d'envoi de messages d'Objective-C. Le nom exact, et la façon dont il est traduit en Objective-C, ont donc une grande importance ici.

Si vous déclarez la méthode func methodName(sender: UIButton) alors son nom en Objective-C est methodNameWithSender: .

Si vous déclarez la méthode func methodName(_ sender: UIButton) alors son nom en Objective-C est methodName: .

iOS et macOS disposent tous deux d'un élément appelé "chaîne de réponse", qui permet au système de rechercher un objet (un "répondeur") capable de gérer une action. Vous pouvez connecter les contrôles de votre storyboard au premier répondeur (en haut du plan du document) pour que le système fasse cela. Le plus souvent, vous faites cela avec des éléments de menu dans macOS, mais il existe d'autres utilisations.

Quoi qu'il en soit, il y a quelques actions standard comme cut: , copy: y paste: . Par exemple, vous pouvez définir l'action de l'élément de menu Cut pour qu'il envoie cut: aux premiers intervenants. Et si vous voulez mettre en œuvre la cut: dans votre contrôleur de vue, il est essentiel que son nom (lorsqu'il est traduit en Objective-C) soit précisément cut: et non cutWithSender: . S'il s'agit d'un nom cut: le système le trouvera lors de la recherche dans la chaîne des répondeurs, mais s'il est nommé cutWithSender: le système pas Trouvez-le et vous vous demanderez pourquoi votre élément de menu ne fonctionne pas.

Xcode le sait, donc il crée toujours des méthodes d'action de la forme @IBAction func action(_ sender: UIButton) Vous pouvez également utiliser l'argument de l'action, en omettant le mot-clé, au cas où vous implémenteriez une action qui doit être trouvée par une recherche dans la chaîne des répondeurs.

Dans Swift 3, chaque argument d'une méthode possède un mot-clé par défaut, y compris le premier argument. Dans Swift 2, le premier argument avait un mot-clé par défaut. pas ont un mot-clé par défaut, de sorte que les _ sur le premier argument était redondant dans Swift 2 (et générait un avertissement du compilateur). C'est la raison pour laquelle Xcode 8 (Swift 3) met en place l'option _ mais pas Xcode 7 (Swift 2.2).

C'est aussi pourquoi votre toggleButtons L'exemple a fonctionné dans Xcode 7.

1voto

Thilo Points 108673

Cela signifie que vous ne devez pas nommer le paramètre lors de l'appel de la méthode.

obj.methodName(button)

// no need for
obj.methodName(sender: button)

Dans les versions antérieures de Swift, c'était le comportement spécial par défaut pour le premier paramètre d'un appel de méthode, mais dans Swift3, ce comportement a été unifié. Tous les paramètres ont maintenant besoin d'un nom, à moins que vous ne choisissiez de ne pas le faire (avec la balise _ ).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X