Swiftでよく使うDelegateってよくわかんないなあ
と、最初は思っていましたが、実装していくうちにわかってきました
概念がわかりにくいかもしれませんが、必ずと言っていいほど1度は通る道なので軽くまとめようかと思います
Delegateとは一体?
最初、Swiftを始めたときに、DelegateはSwift独自のものかと思っていましたが、違いました
ということは、デザインパターンのDelegateパターンを調べてみるとスッと入りやすいかもしれません
デザインパターンなんだと理解したことで少し抵抗がなくなりました
それで、Delegateとは何でしょうか?
Delegateは一般的に「移譲」と言われ、あるクラスから他のクラスに処理を任せるというものです
とは言われてもと思った方は多いはず(自分もそう)なので、サンプル元に説明しようかと思います
Delegateサンプル
import UIKit class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { @IBOutlet weak var TableView: UITableView! override func viewDidLoad() { super.viewDidLoad() TableView.delegate = self TableView.dataSource = self } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 2 } }
これはよく目の当たりにするサンプルだと思います
このViewControllerはTableViewを使うために、UITableViewDelegateとUITableViewDataSourceという2つのプロトコルに準拠しています
tableView(_ tableView, numberOfRowsInSection section)で1セクションの行数を指定しています
最初、これを見たときにどこから呼び出されているのかわからなくて悩んだ記憶があります
そこで、UITableViewのライブラリを見てみましょう
open class UITableView : UIScrollView, NSCoding, UIDataSourceTranslating { weak open var dataSource: UITableViewDataSource? weak open var delegate: UITableViewDelegate?
一部抜粋していますが、UITableViewDelegate
とUITableViewDataSource
の変数を持っています
Delegate
の処理はUITableViewDataSource
で持っているので、そちらを見てみましょう
public protocol UITableViewDataSource : NSObjectProtocol { @available(iOS 2.0, *) func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
こちらも一部抜粋ですが、1セクションの行数を返す処理がプロトコルで定義されています
そして、最初のサンプルのTableView.delegate = self
とTableView.dataSource = self
でTableViewのインスタンスのDelegate先をViewControllerにしています
ここまでで下記のことが分かったと思います
・どのクラスでDelegateを使うか指定する
・Delegateはprotocolで定義する
・Delegateを使うと指定されたクラスではprotocolで指定された関数を記述する
サンプル②
もう一つサンプルを元に説明しようかと思います
まずはDelegateの定義です
protocol ButtonDelegate { // ボタンを非表示にする func hide() }
clickメソッドでDelegateメソッドを実行します
これは処理を任せる側です
class Button { var delegate: ButtonDelegate? = nil func click() { if let dg = self.delegate { dg.hide() } else { print("何もしないっす") } } }
そして処理を任される側の処理を書きます
class Button2: ButtonDelegate { func hide() { print("非表示だぜ!!") } }
こうすることでhide()はButton2に任せる準備ができましたね
let button = Button() let button2 = Button2() button.delegate = button1 button.click() // 非表示だぜ!!が出力される
button.delegate = button1
でbuttonのDelegateをbutton1に任せるのでclickしたときに非表示だぜ!!が出力されます
他のクラスでも使うことがほとんどなのでprotocolで定義しているということがわかるかと思います
まだ?マークの人も多いかもしれません
開発していくうちに理解していけますので、いっぱい実装しましょう
また、Delegateを使わなくても開発できてしまうので、意識して実装すると理解が早まると思います