Help us understand the problem. What is going on with this article?

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

More than 5 years have passed since last update.

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

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()
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした