LoginSignup
587
572

More than 5 years have passed since last update.

プロトコルとデリゲートのとても簡単なサンプルについて

Last updated at Posted at 2014-08-12

デリゲートはよくわかりませんでした。だから、それをとても簡単に説明したいと思います。

Swiftです。

※注意。僕はエンジニアではないので、間違いなどあったらごめんなさい。ご指摘頂けるととても嬉しいです。)

どうでもよい追記:
=> エンジニアのお仕事頂けるようになったので、一応駆け出しエンジニアくらいにはなれました!(^^)/

どうしてデリゲートは分かりにくいのか。

僕はこう思います。

  • 登場人物がはっきりしていない。
  • 定義がはっきりしていない。

(はっきしているかもしれないけど、僕ははっきり理解できなかった。)

ちなみに、上の2つの曖昧なモノのうち、1つは今だに曖昧です。それでも大丈夫です。デリゲートとプロトコルについては理解できます。

登場人物だけおさえれば理解はできると思います。

まずは定義について

教科書(The Swift Programing Language)を読んでみますと、次のようにあります。

Delegation is a design pattern that enables a class or structure to hand off(or delegate) some of its responsibilities to an instance of another type.

簡単に言うと、こうです。

「デリゲートは、デザインパターンです。」

ここで僕は、生まれて初めて「デザインパターン」に出逢いました。

感動的な出逢いです。よく分からないものを調べたら、よく分からないものに出逢う。これ以上の探索をする気がいっきに失せます。

すでに諦めモードですが、せっかくなので、デザインパターンの定義をしらべてみました。個人的には一番すっきりしている定義は以下です。

A design pattern is a repeatable solution to a software engineering problem. (from techopedia)

ということで、デザインパタンの定義について雰囲気だけわかりました…。

分からない部分を無視してデリゲートを簡単に言えば、

「あるクラスは、他のクラスのインスタンスに、処理を任せることができる。」というようなこと。

登場人物について

本題に入ります。登場人物が分かれば、おしまいです。

登場人物は3人。

  • 処理を依頼する人
  • 依頼される人(代理人)
  • プロトコル

以上です。

例をつくります。

依頼するクラスを「Hoge」とします。
依頼される代理人クラスを「Piyo」とします。
そして、そのために使われるプロトコルを「Mochi」としておきます。

表示にすると以下のような感じです。

例)

依頼するクラス プロトコル 依頼されるクラス
Hoge Mochi Piyo
依頼する人 -> 代理人

もう、分かったようなものです。

コードを書いてみます。

Xcode6のplaygroundを使ってコードを書きます。これで説明は終わりです。

playground

// プロトコルを作る。
protocol Mochi {
    func sayHello() -> String
}

// 依頼人クラス
class Hoge {

    // ここで、プロトコルに従うクラスのインスタンスを用意する。
    var delegate: Mochi!
    func say() -> String {
        return delegate.sayHello()
    }
}

// 代理人クラス。クラスの後ろにプロトコルを書く。
class Piyo: Mochi {
    func sayHello() -> String {
        return "Hello, Piyopiyo"
    }
}

let hoge = Hoge()
let piyo = Piyo()
hoge.delegate = piyo    // 代理人を指定。
hoge.say()    // "Hello, Piyopiyo"

ポイントは、var delegate: Mochi!だと思います。(この「delegate」は任意の文字列で大丈夫です。)

改めて、なぜデリゲートが分かりづらいかと言うと。(僕が理解できなかったかと言うと。)

一般的なデリゲートの処理では、このvar delegate: SomeProtocol!が見えないところに存在しているからです。

例えば、キーボードを押し下げるというデリゲートの簡単なサンプルがあります。
http://qiita.com/mochizukikotaro/items/b35c93866fcc55e201f3

SomeViewController.swift

import UIKit

// まず、デリゲートプロトコルを宣言
class ViewController: UIViewController, UITextFieldDelegate {

    // テキストフィールドをアウトレット接続して
    @IBOutlet var textHoge : UITextField

    override func viewDidLoad() {
        super.viewDidLoad()

        // selfをデリゲートにする
        self.textHoge.delegate = self
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    // selfをデリゲートにしているので、ここにデリゲートメソッドを書く
    func textFieldShouldReturn(textField: UITextField!) -> Bool {
        self.view.endEditing(true)
        return false
    }
}

登場人物は、

  • 代理人クラス:ViewController
  • 依頼人クラス:UITextField
  • プロトコル:UITextFieldDelegate

です。が、ここでUITextFieldの中身がどう書かれているかなんて普通見ません。素人は。中身はこうなっていました。

UITextField

class UITextField : UIControl, UITextInput, UIKeyInput, UITextInputTraits, NSObjectProtocol, NSCoding {
//中略
var delegate: UITextFieldDelegate! // default is nil. weak reference
//中略
}

だから、self.textHoge.delegate = selfと書けば、ちゃんと処理を委任できるんですね。

こんなことは、「べつに普通じゃん。簡単じゃん。」と言われれば、そうなのかもしれないですが、僕としては、

var delegate: UITextFieldDelegate!という記述を、自分の目で見ないと、どこに書いてあるのか把握できないと、納得感がないのです。

だから、その辺の参考書を読んでも、デリゲートとかプロトコルについて全然分かんないんです。そもそもデリゲートの説明で、プロトコルの説明なかったりしますし。

以上です。

ちなみに、上の例はデリゲート(プロトコル)を使わなくてもできます。

playground

class Hoge2 {    
    var delegate: Piyo2!
    func speak() -> String {
        return delegate.say()
    }
}

class Piyo2 {    
    func say() -> String {
        return "こんにちは!"
    }
}

var hoge2 = Hoge2()
var piyo2 = Piyo2()
hoge2.delegate = piyo2
hoge2.speak()
587
572
12

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
587
572