delegate と protocol
Update on March 17, 2016
View ControllerとTable Viewを例にして、
「delegate」と「protocol」について整理してみました。
確認環境:Xcode 7.2
ユーザーは、テーブルビューのセルをタップしたり、スクロールしたりします。
この時に発生したイベントのいくつかを、テーブルビューが処理するのではなく、
ビューコントローラーに処理を任せます。
このことを、デリゲート(delegate)と言います。
例として、
「TEST001TableView」Table Viewを配置した「TEST001ViewController」View Controllerがあるとします。
「TEST001TableView」Table Viewがデリゲートする側です。
「TEST001ViewController」View Controllerはデリゲートされる側です。
実装は、デリゲートされる側の「TEST001ViewController」View Controllerに、以下のようにします。
デリゲートする側の「TEST001TableView」Table Viewには、特に何も実装しません。
デリゲートする側の「TEST001TableView」クラスは、「delegate」プロパティがあります。
この「delegate」プロパティに、デリゲートされる側の「TEST001ViewController」クラスを指定します。
「TEST001ViewController.m」で実装しているので、自分自身である「self」となります。
TEST001ViewController.m
「TEST001ViewController.h」で
@interface の箇所に <UITableViewDelegate> と記述します。
この <UITableViewDelegate> が、デリゲートプロトコルメソッドです。
TEST001ViewController.h
<UITableViewDelegate> デリゲートプロトコルメソッドの中身を見てみましょう。
エディター上で、「command」キーを押しながら、<UITableViewDelegate> の箇所をクリックします。
こんな感じで「UITableViewDelegate」にどんなメソッドがあるか確認できます。
UITableView.h
1行目に
@protocol UITableViewDelegate < NSObject, UIScrollViewDelegate>
とありますが、
これが、「UITableViewDelegate」という名前のプロトコルであることを表しています。
一般に、クラスは、そのクラス固有のメソッドやプロパティを持っていて、ヘッダーファイル(.h)に、メソッドやプロパティを宣言します。
これに対して、プロトコルとは、どのクラスにも結びついていないメソッドやプロパティを定義したものです。
どのクラスにも結びついていないものなので、プロトコルを使用するには、クラスに結びつける必要があります。
この例の場合、デリゲートされる側の「TEST001ViewController」クラスのヘッダーファイル「TEST001ViewController.h」の
@interface の箇所に <UITableViewDelegate> と記述し、
「TEST001ViewController」クラスが、「UITableViewDelegate」プロトコルを使用する旨を宣言します。
あとは、「TEST001ViewController」クラスのソースファイル「TEST001ViewController.m」に、
「UITableViewDelegate」プロトコルで宣言されたメソッドを実装します。
この例の場合は、3行目に「@optional」と記述されています。
これは、3行目以降に宣言されたプロトコルのメソッドが、必須ではなく、任意であることを示しています。
なので、「TEST001ViewController.m」にこれらの「UITableViewDelegate」プロトコルメソッドを実装しても、しなくてもOKです。
なお、以下は「UITableViewDataSource」プロトコルメソッドですが、
3行目に「@required」と記述されています。
これは、12行目の「@optional」より上に記述された、以下の2つのプロトコルメソッドが、必須であることを示しています。 ・numberOfRowsInSection ・cellForRowAtIndexPathなので、「TEST001ViewController.m」に、この2つのプロトコルメソッドを実装しないと、コンパイラが警告を出します。
UITableView.h
これで、「TEST001ViewController」クラスは、「TEST001TableView」クラスからデリゲートされまた。