【コラム】

ダイナミックObjective-C

9 プロトコルが必要とされた背景とは? - なぜあえて静的な型を?

    木下誠  [2005/10/05]

    前回と同様、Objective-Cでのメソッド宣言にまつわる話を続けよう。今回は、メソッドの集合を宣言するプロトコルだ。

    プロトコルによるメソッドの集合の宣言

    プロトコルは、オブジェクトの振る舞いを表すメソッドの集合を定義するものだ。@protocolという指示子で宣言する。

    具体的な例を見てみよう。次のコードは、NSCodingというプロトコルを宣言するものだ。これは、オブジェクトをエンコード、デコードするためのメソッドを定義する。この2つのメソッドで、オブジェクトの保存/読み込み機能を実装する。

    @protocol NSCoding
    - (void)encodeWithCoder:(NSCoder*)coder;
    - (id)initWithCoder:(NSCoder*)decoder;
    @end

    オブジェクトがこのプロトコルを採用することを、プロトコルに適合している、という。文法的には次のように書く。

    @interface MyObject : NSObject <NSCoding>
    {
        ...
    }
    ...
    @end

    このように宣言することで、このオブジェクトが、保存/読み込み可能という特性を持つことをアピールできるわけだ。あるオブジェクトがプロトコルに適合しているかどうかを実行中に調べることもでき、conformsToProtocol:というメソッドを使用する。

    ちなみに、プロトコルではインスタンス変数を宣言することはできない。あくまで、メソッドの振る舞いに関するものだけである。

    プロトコルは何のために?

    さて、そんなプロトコルであるが、どんな利点があるのだろう。実際に使ってみると分かるのは、まず、コンパイル時にメソッドのチェックをして警告を出してくれる。Objective-Cの常で、警告は出てもコンパイルは通るのだが。

    だが、これはいままで説明してきたことと矛盾しないだろうか。この連載では、Objective-Cの利点は動的なメソッド判別にある、と繰り返し解説してきた。静的なメソッドのチェックを助けるような、プロトコルは何のためにあるのだろうか。

    ここを理解するには、この機能が、なぜ「プロトコル」という名前なのかを知る必要がある。プロトコルという単語は、ネットワークの「通信規約」という意味などで使われることが多い、Objective-Cのプロトコルも、ここに由来するのである。

    プロトコルとプロセス間通信

    ここでいったんCocoa環境に話を移そう。Cocoaでは、オブジェクトのスレッド間、あるいはプロセス間での、メッセージ通信が実現されている。2つの異なるプロセスにあるオブジェクトが、通常のものと同じように、メッセージをやり取りすることができる。

    この機能のために、プロキシとコネクションと呼ばれる機能がある。メッセージを送る際は、相手のオブジェクトの「代理人」となるプロキシを作り、メッセージをエンコードして、コネクションを通して、相手に届くことになる。

    プロセス間のオブジェクト間通信

    さて、プロセス間通信は、とても時間がかかる。パフォーマンスのために、可能な限り無駄な通信は控えたい。だが、通信時のメッセージのエンコード方法を知っているのは、通信先の相手である。相手先にメッセージの型を問い合わせるので、通信が二度手間になってしまう。

    そこで、メッセージのエンコードに関する情報をあらかじめ与えるために、プロトコルが使われるのである。つまり、プロトコルには規約という意味があると書いたが、オブジェクトのプロセス間通信のための規約なのである。実際に使用するときは、プロキシに対して、setProtocolForProxy:というメソッドを使い、プロトコルを当てはめてやる。こうすることで、そのプロキシはメッセージのエンコード方法が分かることになり、無駄なプロセス間通信を減らすことができる。

    プロトコルを当てはめる

    一般的に、動的な特性を利用する言語は、静的言語に比べてパフォーマンスの面で不利とされる。特に、プロセス間通信のような時間のかかる処理が絡むと、その影響はより大きくなる。そこで、あえてプロトコルを使い、静的な型をはめ込むようなことをして、この問題を回避しようとしているのだろう。

    実際にCocoaのフレームワーク調べてみると、プロトコルは、ドラッグ・アンド・ドロップや、文字入力などの、プロセス間通信が必要なクラスに採用されている。パフォーマンスを上げるための努力を見ることができる。

    今回は、プロトコルのプロセス間通信サポートの面に着目したが、もう一つの面である、オブジェクトの振る舞いを表す、という機能も便利である。次回は、この辺りを説明しよう。

    新着記事

    特設サイトの情報

      人気記事

      一覧

        イチオシ記事

        新着記事

        特別企画

        マイナビニュースマガジン