Objective-CでのDelegateについて

Konton's iPhone application labolatory

English top page

Objective-CでのDelegateとは

iPhoneアプリケーション開発において、結構頻繁に出てくるのがこのDelegateという言葉です。プロジェクトを作れば必ず~AppDelegateというクラスが作られますし、 他にも様々な場面で~Delegateというものを目にすることになります。Delegateとは代理人とか代表者とか委譲などという意味があります。 通常あるオブジェクトへと送られてくるメッセージはそのオブジェクトで処理するべきなのですが、いちいちそのオブジェクトのファイルを作るのは面倒という場合があります。 その場合に、別のクラスに送られてきたメッセージを丸投げしてしまうと、そのオブジェクト自体に特有の処理を書くなどしなくて良くなるため便利、というわけです。

たとえば、iPhoneアプリケーションで画面にメッセージを表示するUIAlertViewというクラスがあります。 あるViewControllerから場面により複数のUIAlertViewを表示させる場合を考えてみます。 それぞれのUIAlertViewがユーザーに何かを選んでもらうためにボタンを数個用意しているとしましょう。 このとき一つ一つの表示用にUIAleartViewからカスタマイズしたクラスを作って(これをプログラムの専門用語ではUIAleartViewを継承したサブクラスの作成と言います)、 それぞれの反応についてを別々のメソッドファイルに記述し、それぞれからViewController側へメッセージを送って情報を回収することも出来ます。 それこそがオブジェクト指向プログラミングの目指すべき姿、なのかもしれません。 でもそれよりも表示の開始を指示したViewController自体を反応の受け取り手にしてしまい、それらの情報処理を全て一手に引き受けさせたほうがよりシンプルな構造にできます。 Delegateの仕組みを使えばUIAlertViewとは全く関係ないクラスでも情報の受け取り手になれるため、このようなことが出来るわけです。


Delegeteへの対応方法

では具体的な利用方法について書きましょう。Delegeteの仕組みを利用して他へと処理を丸投げしたい側は、自分のdelegeteへ相手先のオブジェクトをセットします。 セットの方法は初期化のメソッド内で引数により指定する場合や、setter(setDelegate:)で指定する場合などがあります。そして丸投げをされる側は自分のヘッダにある@interfaceで、 自分はこのクラスからの情報を代理として受け取るよという「代理人であることを示す印」を設置します。専門的な言葉では、 「SettingTableViewControllerはUIAlertViewDelegateプロトコルを採用している」と表現するようです。先ほどの例でいくと、

@interface SettingTableViewController : UITableViewController <UIAlertViewDelegate> {
    (中略)
}

この<と>ではさまれた部分に書かれたUIAlertViewDelegateが代理人の証です。同時に何個ものDelegeteに対応することもでき、その場合は、

@interface Tiny3DAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate, UIAccelerometerDelegate> {
    (中略)
}

上のように<>内にカンマ区切りで列挙します。SettingTableViewControllerは見ての通りUITableViewControllerが元になっているので、 本来はUIAlertViewのメッセージを受け取れません。でもこの代理人の証さえあれば、 自分のメソッド内から呼び出したUIAlertViewのdelegateを自分自身(self)にすることで、ユーザーの反応結果を受け取ることができます。 ちなみにInterface Builderでdelegateを接続した場合にはこのような記述は不要です。また、クラスによってはそのDelegateになっているのは当たり前、と認識されているものもあります。 たとえばUITableViewControllerクラスはUITableViewDelegateおよびUITableViewDataSourceについてはヘッダへの記述は不要となっています。 なお、Delegateの種類によって、代理人の側が用意すべきメソッドは変わります。 Delegate側で必須および必須でないメソッドが定義されており(これらの定義をプロトコルと呼んでいます)、必須のメソッドについては全て取り揃えておかないとビルド時にエラーが起きます。 必須でないメソッドは準備しなくてもエラーは起きません。例えばUIAlertViewのDelegateになっている場合に、 受け取りに使う必須メソッドは以下のものです。

- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex;

 複数のUIAlertViewのDelegeteになることもできるため、送り元がどのUIAlertViewであるかを受け取る1個目のUIAlertview *型の引数があり、何番目のボタンが押されたのかを受け取る2個目のNSInteger型の引数があります。UIAlertViewを作った時にタグを設定しておけば、 そのタグの値から何の選択用に作ったUIAlertViewだったか判断することが可能です。なお、Delegete全般に言えることですが、 ヘッダでこのようなメソッドを宣言しておく必要はありません。メソッドファイルに必要なメソッドを記載しておくだけで大丈夫です。

前へ次へ
Copyright© 2009 Konton All rights reserved. - このサイトについて - サイトマップ

Valid XHTML 1.1 正当なCSSです!