LoginSignup
0
1

More than 1 year has passed since last update.

SwiftのProtocolとdelegateを理解する

Last updated at Posted at 2021-07-30

Protocolとdelegateの関係

Protocoldelegateの関係は密であり、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()
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1