Protocolとdelegateの関係
Protocol
とdelegate
の関係は密であり、Protocalでdelegateを実装する
という関係です。
delegateを知る
-
delegate
は使わなくてもいい - メリット:クラス側に処理の内容を任せるのではなく、自分で処理を決めることができる。
Protocolでdelegateを実装
protocol ButtonDelegate {
func delegateClicked()
}
delegateを変数として宣言
class Button {
var delegate: ButtonDelegate?
func clicked() {
if let delegate = delegate {
// 自分で実装した処理
delegate.delegateClicked()
} else {
// 通常の処理
print("クリックされました")
}
}
}
Mainクラスを実装
ここから実際にMain
クラスでのdelegate
の使い方を説明していきます。
冒頭で説明したようにdelegate
は必ずしも必要なわけではないので、Button
クラスでdelegate変数
を宣言しましたが、使用しない方法を説明していきます。
delegateなしの場合
class Main {
let button = Button()
func clicked() {
button.clicked()
}
}
let main = Main()
main.clicked() // 「クリックされました」とprintされる
delegateありの場合
Class
は継承ですが、Protocol
は適合といいます。
class MainWithDelegate : ButtonDelegate { // ButtonDelegateを適合
let button = Button()
init() {
button.delegate = self // delegateをインスタンス化
}
func clicked() {
button.clicked()
}
// 自前でdelegateClicked()を実装
// Protocolを適合したので、ButtonDelegate内で宣言された関数の処理を実装しないとコンパイルエラーになる
// deletgateClicked()はButton.Click()時に呼ばれる
func delegateClicked() {
print("クリックされたよー")
}
}
let mainWithDelegate = MainWithDelegate ()
mainWithDelegate.clicked() // 「クリックされたよー」とprintされる
delegateのポイント
delegate
で実装した関数は自分で呼び出すわけではない
今回の例では、勝手にclicked()
関数が呼び出している。なので実装しておしまいです。呼び出す必要はありません。
別の例
Figureクラスを使いたいがgetArea()
が通常の処理では、横×縦の値が返ってくるが、それを2倍にする処理にしたい
protocol FigureDelegate {
func getAreaDelegate() -> Int
}
class Figure {
var delegate : FigureDelegate?
let width : Int
let height : Int
init(width: Int, height: Int) {
self.width = width
self.height = height
}
func getArea() -> Int {
if let delegate = delegate {
return delegate.getAreaDelegate()
}
else {
return self.width * self.height
}
}
}
class Main : FigureDelegate {
let figure = Figure(width: 5, height: 7)
func setDelegate() {
figure.delegate = self
}
func printArea() {
print(figure.getArea())
}
func getAreaDelegate() -> Int {
return self.figure.width * self.figure.height * 2
}
}
let main = Main()
main.printArea()
main.setDelegate()
main.printArea()