UIButton タップ時の処理などを IBAction で紐付けるとき、 型は Any がデフォルトなので、そのままにする人も多いのではないでしょうか。

final class FooViewController: UIViewController {
@IBAction private func didTapCloseButton(_ sender: Any) {
}
}
それだとキャストしないと型に応じた処理を実行できないので、具体的な型を選択して紐付けるのが望ましいです。

final class FooViewController: UIViewController {
- @IBAction private func didTapCloseButton(_ sender: Any) {
+ @IBAction private func didTapCloseButton(_ sender: UIButton) {
}
}
デフォルトが Any なので、それを選択したほうがいい理由もあるのかと思っていたのですが、どうやらObjective-Cの仕様なだけのようなので、 Any を選択するメリットはなさそうです。
具体的な型入れて方がsenderに応じた処理書きやすいです;Anyになってるのは単純にObj-Cのselectorの仕様なだけです
— 星野恵瑠#今日も1日フレンズ㌠ (@lovee) June 16, 2020
おまけ1: そもそも sender とは?
「send + er」で、一言でいうと「対象アクションのトリガーとなったUI」です。
例えば上記の @IBAction private func didTapCloseButton(_ sender: UIButton) だと、 sender にはタップされたボタン(メソッド名から「閉じる」ボタンだと推測できる)が格納されています。
メソッド名は自由に付けられますが、私はわかりやすいように、ボタンのタップなら didTap○○Button(_:) と命名しています。
おまけ2: 他の考え方
Twitterなどを見ていると、他にもいろいろな考えを持っている方がいたので紹介します。
-
senderを使わないときは特に意識せず(Anyのまま)、使うときのみ具体的な型に変更する -
senderを使わないときは引数ごと削除し、使うときに引数を追加する
使うときに具体的な型を指定するのを忘れなければ、どちらの考えもいいと思います。
ただ、 IBAction の仕様がわからなくて sender を Any のまま使われるのを避けるため、私は常に具体的な型の sender を引数に持たせるのがいいと考えています。
具体的な型の sender があると、どのUIに紐付いたアクションなのかコードから読み取りやすくなるのもあります。
final class FooViewController: UIViewController {
// 「これは「閉じる」ボタンタップ時の処理だな!」と `sender` の型とメソッド名からパッと判断できる
@IBAction private func didTapCloseButton(_ sender: UIButton) {
}
}