【学習備忘録】(Swift)デリゲートパターンを使ったCocoaMVCモデル
はじめに
前回、NotificationCenterを使用したCocoaMVCモデルについて学習し、今回はデリゲートパターンを使ったCocoaMVCモデルの実装をしたいと思います。
デリゲートパターンとは
簡単にいうと、あるオブジェクトが本来行うべき業務(ロジック)の一部を別のオブジェクトに委ねる設計パターンです。
こういう設計にしておくことで、開発者がそのクラスのオブジェクトを使う時に多様な使い方や制御ができ、 汎用性が増すことになります。
出典:https://dev.classmethod.jp/articles/delegate-protocol-writing-and-concepts/#toc-8
CocoaMVCについて
前回の記事を参照いただければ幸いです。
サンプルコード
挙動は前回と同様です。
1.protcolを定義する
テキストをチェンジするメソッドをもつプロトコルを定義する。
protocol TextModelDelegate: AnyObject {
func didChangeText()
}
2.Modelを実装
changeTextメソッドが呼ばれたときに、テキストを変更しnotify(通知)メソッド(デリゲートの委任処理)が呼ばれるようにする。
class TextModel {
weak var delegate: TextModelDelegate?
private(set) var text = "ボタンを押してください"
func changeText() {
text = "ありがとう"
notify()
}
private func notify() {
delegate?.didChangeText()
}
}
3.ViewControllerを実装
・ViewControllerをTextModelDelegateに適合させる。(可読性を上げるため、extentionで適合させています。)
・textModel.delegate = selfと記載し、ViewController内での処理を記載することを示す。
・TextModelDelegateに適合させた、ViewControllerのdidChangeTextメソッドにupdateLabelのメソッドを記載する。
class ViewController: UIViewController {
@IBOutlet private weak var label: UILabel!
private let textModel = TextModel()
override func viewDidLoad() {
super.viewDidLoad()
setupLabel()
textModel.delegate = self
}
@IBAction private func pressedButton(_ sender: Any) {
textModel.changeText()
}
private func setupLabel() {
label.text = textModel.text
}
private func updateLabel() {
label.text = textModel.text
}
}
extension ViewController: TextModelDelegate {
func didChangeText() {
updateLabel()
}
}
これで、Modelのテキストを変更した際に、ViewControllerに変更が通知され、テキストが変更されるという処理が実現できました。
GitHub
参考にしたもの
1.delegate(デリゲート)について徹底解説します!【Swift】
2.#25 Swiftでテーブルビュー(UITableView)のカスタムセルを作る/チャットの質問への回答・アプリ道場ライブ
iOSアプリ設計パターン入門
さいごに
デリゲートについて、学習初期はわからないことだらけでしたが、デリゲート処理でどのような問題点を解決できるのか意識することでより理解しやすいものとなりました。
間違いや認識違いがあれば指摘いただければ幸いです。
Discussion