タイトル今から始めるCocoaプログラミング》ドラッグ&ドロップでファイルを開く(1)DelegateについてカテゴリーCocoa, 今から始めるCocoaプログラミング
作成日2001/4/27 16:32:50作成者新居雅行
このシリーズは、2000年12月にInterface BuilderとProject Builderを使った基本的な開発手法をまずお届けし、そこではOutletsとActionについての概念を詳しく説明した。Interface Builderで設定をすることにより、プログラム内でテキストフィールドなどのコントロール類を参照する方法などを示した。また、2001年3月には、抽選用アプリケーションがそこまでの知識で簡単に作成できることも示した。その続きで、今回はアプリケーションの起動を行う場面を中心に説明をしたい。ダブルクリックして起動するアプリケーションが作成できるのは、Mac OS X向けにビルド可能なProject Builderでは当然のことだとして、やはり目指すはドラッグ&ドロップによって起動し、さらにはそのファイルを読み込むなどの処理につなげたい。もちろん、起動時だけでなく、起動後にドラッグ&ドロップもあるだろう。ドラッグ&ドロップにはFinderの項目間でもあるが、起動したアプリケーションはDockにアイコンも表示され、そこへのドラッグ&ドロップもある。なお、Finderからのドラッグ&ドロップは、FinderでのアプリケーションアイコンでもDockのアイコンでもプログラム上では同じイベントとなるため、それぞれ機能を組み込むという必要はないことは最初に押さえておこう。

従来までのMac OS向けアプリケーションでも、ドラッグ&ドロップが可能だったが、これは、OpeDocumentsと呼ばれる種類のAppleEventに対応する必要があった。C言語でフレームワークなどを使わないとすると、AppleEventのハンドラとなる関数を記述し、その関数が所定のイベントで呼び出されるようにするといった処置が必要だった。このイベントはFinder絡みでもあったので、「Finderイベント」としてひとくくりにされることもあったが、いずれにして、そうしたイベント処理を組み込むのがポイントであった。イベントを登録する処理や、あるいはイベントからパラメータを取り出す処理などが煩雑であったので、このあたりはプログラミングを進める上での関門にもなっていた。
Mac OS Xでもやはり同様な仕組みが働いている。少なくとも、Carbonアプリケーションでは、そうしたOpenDocumentsというAppleEventの処理を組み込むことになる。背後でどう動いているかまでは分からないが、こうしたイベントはFinderだけでなくDockで表示されているアプリケーションに対してドラッグ&ドロップしても発生する。

同じように、Cocoaアプリケーションでもやはりドラッグ&ドロップを受け付ける仕組みが作られているが、こちらはフレームワークに機能が組み込まれているので、AppleEventを直接処理することはまずしなくてすむというメリットがある。まずはその考え方から説明したい。「イベント」ということをまずは概念的に理解してもらいたい。Mac OSの頃からのイベントと同じように、実行しているソフトウエアの内部で「何か起こった」ということをイベントと考える。もちろん、何か起こることをどうやって検知するのかといった問題も知りたいところだが、フレームワークを使うときにはまずはどんなイベントが起こるのかという点に注目しよう。イベントにはいろいろあるのだが、フレームワークでサポートしているイベントの処理を理解するというのがまずは第一歩となる。
Cocoaのフレームワークで作成されるアプリケーションは、NSApplicationクラスの1つのインスタンスであるというのが大前提だ。このクラスはアプリケーション作成ではきわめて重要なので、ドキュメントについては是非とも目を通しておこう。このアプリケーションの中でさまざまなイベントが発生し、それに対する処理が行われているように作られている。
また、イベント以外にNotification(通知)という機能もある。これは、何かあったときに別のオブジェクトからメッセージが送られるという形式のものだ。通常、Notificationはその発生をあらかじめ予約しておき、何かが起こればメッセージ送信(具体的にはメソッド呼び出し)が行われるという具合である。今回の記事ではその部分的な使い方を説明するが、その範囲内ではイベントもNotificationも同じようなものと思われるかもしれない。だが、フレームワーク内での動作としては違うものであるので注意をしておいてもらいたい。

ではそのイベントが発生したことをどうやれば知ることができるのだろうか? NSApplicationのインスタンスで発生したとは言っても、どうやってイベントに対応した処理をすればいいのかということになるが、もちろんそうした機能をフレームワークで用意している。その機能がDelegate(委譲)と呼ばれる機能だ。JavaでもJDK 1.1以降ではDelegateに基づくイベント処理が行われているので、Javaに詳しい人はピンと来るかもしれない(もっとのその後にイベントモデルを指す言葉としてDelegateは使わなくなったが…)。要は、イベント処理を別のオブジェクトにまかせてしまうというやり方なのである。Javaのライブラリ機能ではさまざまな処理形態が組み立てられるものの、ちょっと気持ちを入れない理解はできなかったかもしれない。CocoaのDelegateはJavaのものに比べてもっとシンプルなのである。1つの方法であるが、おまかせするという設定を、Interface Builder上でできてしまうのだ。しかも、まかせられた側のクラス設計の縛りも弱く、必要なイベント処理だけの記述で良い。本質的に悪いというわけではないが、Javaではabstractクラスで定義された決められたクラスを元にしたり、メソッドを全部定義しないといけないこともあるなど規則の上ではやや厳しい面があるのと比べれば、CocoaのDelegateはシンプルに利用することができる。

□Delegateにより処理を別のオブジェクトにまかせることができる


ここで少し具体的にどんなイベントがあるかを紹介したいが、もうご想像されているかと思うが、Finderからファイルをドラッグ&ドロップしてくると、それを受けてNSApplicationではイベントが発生する。しかしそのままでは、ドラッグ&ドロップしたファイルの処理ができないので、NSApplicationから別クラスのオブジェクトにDelegateを設定しておく。すると、イベント処理がDelegateしたオブジェクトに投げられる。具体的には、Delegateしたオブジェクトの規定のメソッドが呼び出されるのである。もちろん、そのメソッドでは、ドラッグ&ドロップしてきたファイルが何かを知ることができる。こうしてドラッグ&ドロップしてきたファイルの処理を自分で作成することができるのだが、次回以降示すように、その処理の組み立ては実にシンプルに記述できるのである。プログラムがシンプルなのは、オブジェクト間の関連付けなどをInterface Builderでできるからだとも言えるだろう。
Notificationの例も示しておこう。NSApplicationでは、アプリケーションの起動処理が始まったときや終了したときに、Notificationが発生するような仕組みになっている。Notificationを起こすようなプログラムが、NSApplicationに組み込まれているので、プログラマから見れば自動的に発生するとように見えるだろう。ここで、NSApplicationから別のオブジェクトにDelegateすると、NotificationはDelegateしたオブジェクトの方にメッセージングされるのである。つまり、Delegateしたオブジェクトに規定のメソッドを書いておけば、Notificationが発生したときにそのメソッドが呼び出されるというわけだ。だから、Notificationを受けて独自の処理を実行させることができる。
これらのイベントやNotificationを利用して、ドラッグ&ドロップされたファイルの処理を行ったり、さらにはダブルクリックして起動したときに別の処理を行うといった機能をCocoaアプリケーションとして作り上げるポイントを説明しよう。具体的には次回以降に説明を行う。

なお、こうしたDelegateのメカニズムは、NSApplicationだけではなく、ウィンドウやコントロールなど、Cocoaフレームワークのいたるところで見られる。Delegateをうまく使うことが、Cocoaフレームワークを使う上での1つのポイントになるとも言えるだろう。
(この項続く)
関連リンク