そもそもdelegateってなんだ
言葉を調べてみる
delegateを辞書で調べてみると、
1.委任する
2.代表[代理]に立てる
という意味らしい。
なるほど、言葉の意味は分かった。
Swift的観点で調べる
では、Swiftにおいて、delegateってなんだ?ともう少し調べてみると、
「delegateとは、デザインパターンのひとつです。」
なんて出てきた。
なるほど、分からないようで分からない。
分からんかったからさらに調べる
さらに調べていくと、TECHACADEMYにたどり着いた。
https://techacademy.jp/magazine/15055
ここでは、
『実際のイメージとしては「ある特定の事項について、問い合わせ先を指定する」操作と覚えておくと分かりやすいです。』
と書いてあった。
delegate = 問い合わせ先とも書いてあって、これが一番理解しやすいような気がする。(なんとなく)
まあ、とりあえず実装してみないと分からないイメージつかないので、実装に移りたい。
delegateを実装するために必要なもの
1.protocol
委任する処理をmethodとして定義する。これをデリゲートメソッドと呼ぶ。
言わば「仕様書」と言ったところ。
2.処理を委任するclass
デリゲートメソッドを使用して、処理の流れを記述する。
3.処理を委任されるclass
protocolで定義されたデリゲートメソッドを実装する。
実際に実装してみる
1.protocol
メソッドを定義する。
protocol horseDataDelegate {
func horseName() // 競走馬名
func horseBirthYear() // 競走馬の誕生年
func horseWinNumber() // 競走馬の勝利数
func horseIsLeadingSire() // 競走馬の種牡馬状況
}
2.処理を委任するclass
今回はViewController内に実装した。
import UIKit
class ViewController: UIViewController {
var delegate: horseDataDelegate? //delegateを定義
override func viewDidLoad() {
super.viewDidLoad()
//使用するdelegateをここで呼び出す
delegate = DeepImpact()
//delegate内のメソッドを呼び出す
delegate?.horseName()
delegate?.horseBirthYear()
delegate?.horseWinNumber()
delegate?.horseIsLeadingSire()
}
}
3.処理を委任されるclass
protocolに記載したメソッドを使用して記載する。
class DeepImpact: horseDataDelegate {
func horseName() {
print("Horse Name is Deep Impact")
}
func horseBirthYear() {
print("Horse was born in 2002")
}
func horseWinNumber() {
print("Horse won 12")
}
func horseIsLeadingSire() {
print("Horse is Leading Sire")
}
}
これでRunすると、こんな感じで出力される。
Horse Name is Deep Impact
Horse was born in 2002
Horse won 12
Horse is Leading Sire
共通なメソッドをprotocolに用意する
ここでまとめても良かったが、もう少し突っ込んでみる。
horseDataDelegateのクラスをもう一つ作成してみた。
class Orfevre: horseDataDelegate {
func horseName() {
print("Horse Name is Orfevre")
}
func horseBirthYear() {
print("Horse was born in 2008")
}
func horseWinNumber() {
print("Horse won 12")
}
}
ViewControllerのdelegateもこれに伴って変更してみる。
import UIKit
class ViewController: UIViewController {
var delegate: horseDataDelegate? //delegateを定義
override func viewDidLoad() {
super.viewDidLoad()
//delegate先を変更
delegate = Orfevre()
delegate?.horseName()
delegate?.horseBirthYear()
delegate?.horseWinNumber()
delegate?.horseIsLeadingSire()
}
}
これでRunすると、Orfevreクラスでエラーが出る。
Type 'Orfevre' does not conform to protocol 'horseDataDelegate'
horseIsLeadingSireメソッドないよ!って言われてる。
基本的にprotocolに記載されているものは全部書かないといけない。
が、共通でもいいメソッドがある時は、わざわざ全部のメソッドを書く必要もない.
そこで、protocolを少しだけ修正する。
protocol horseDataDelegate {
func horseName() // 競走馬名
func horseBirthYear() // 競走馬の誕生年
func horseWinNumber() // 競走馬の勝利数
func horseIsLeadingSire() // 競走馬の種牡馬状況
}
extension horseDataDelegate {
// このメソッドはデフォルトで実装しておく
func horseIsLeadingSire() {
print("Horse is not Leading Sire")
}
}
共通で使用するメソッドは、このように、extensionで用意しておけばいい。
Orfevre.swift内のhorseIsLeadingSire()は、これをオーバーライドしているという形になる。
これでRunが通る。出力はこんな感じ。
Horse Name is Orfevre
Horse was born in 2008
Horse won 12
Horse is not Leading Sire
本当は、もう少し書きたいことがあったけど、長くなりそうなので今回はここまでで。
最後に
今回作成したものはGithubに載せています。
https://github.com/taichi6930/SwiftDelegateSample
初めてQiitaに投稿してみました。
やはり文章を書くのは難しいですね。
とはいえ、自分の頭の中で整理しながら書くことができました。
これからも続けていきたいと思います。