Swift2.1以前と2.2以降の比較
Swift2.1以前の書き方
ViewController.swift
let button = UIButton(type: .System)
button.addTarget(self, action: Selector("buttonTapped:"), forControlEvents: .TouchUpInside)
func buttonTapped(sender: UIButton) {
//Button Tapped
}
セレクターは文字列を指定して生成していたのでtypoしていてもコンパイル時に気づくことができなかった
Swift2.2の書き方
#selector
が導入されたことで下記のような書き方に変わった
ViewController.swift
let button = UIButton(type: .System)
button.addTarget(self, action: #selector(ViewController.buttonTapped(_:)), forControlEvents: .TouchUpInside)
func buttonTapped(sender: UIButton) {
//Button Tapped
}
これによりtypoしてもエラーが出るので安全になった
課題
- Swift2.1以前の時よりも1行のコード量が増える
//Swift2.1以前
button.addTarget(self, action: Selector(“buttonTapped:”), forControlEvents: .TouchUpInside)
//Swift2.2以降
button.addTarget(self, action: #selector(ViewController.buttonTapped(_:)), forControlEvents: .TouchUpInside)
- 大きなViewControlerになると色々なイベントのアクションとしてセレクターを使うけれど、セレクターがViewControllerの様々な箇所に散らばりがち
- 複数から同じセレクターの処理を使う時にどうやってまとめるべきか
要は可読性をもっと良くしたいよね
解決方法
ViewControllerごとにSelector
構造体をprivate拡張してセレクターのタイププロパティを生やしてあげる
ViewController.swift
private extension Selector {
static let buttonTapped = #selector(ViewController.buttonTapped(_:))
}
呼び出し側は下記のようになる
ViewController.swift
let button = UIButton(type: .System)
button.addTarget(self, action: .buttonTapped, forControlEvents: .TouchUpInside)
-
button.addTarget(self, action: #selector(ViewController.buttonTapped(_:)), forControlEvents: .TouchUpInside)
と書いている場合よりずっと簡潔に書ける - ViewControllerが大きくなってセレクターを使ったイベント処理が増えた時も、セレクターの生成は
Selector
構造体にタイププロパティを拡張して増やすことにより、セレクター生成処理のコードが散らばらないし、セレクターの修正とかしたい時も1箇所にまとまっているから簡単にできるし可読性が上がる気がする
まとめ
ViewControllerごとにセレクターを一元管理することで可読性があがるよね
というようなことが ここ に書いてあり、良いと思ったので共有です