CocoaBindingによってコーディング方法はどのように変化するのか?

「スラーダーを動かすと、連動してテキストフィールドの数値が変化する」という単純なサンプルアプリを作ってみた。

詳細な仕様としては...

  • Sliderを動かすと、連動してTextFieldの数値が変化する。
  • TextFieldに数値を入力すれば、Sliderが数値に対応した位置に移動する。

Cocoaフレームワークでのはじめの一歩、Hello World的なコードだ。上記の仕様を実現するために、かつては以下のような作業をしていた。

伝統的なターゲット・アクションによる方法

  • ウィンドウにスライダーとテキストフィールドを配置する。(スライダーのContinuousはチェックありに*1

  • NSObjectを追加して、AppControllerを作る。(モデル、コントローラー兼用)
  • AppControllerにアクション(GUIの操作に対応したメソッド)updateSlider:とupdateTextFieldを追加する。
  • AppControllerにアウトレット(GUI部品であるスライダーとテキストフィールドへの参照)sliderとtextFieldを追加する。

  • 上記アクションとアウトレットを接続して作業完了。(以下はアクションupdateSlider:を接続する作業例。同じようにすべてのアクションとアウトレットを接続した。)

作業の大部分でInterface Builderを利用して、その設定をXcodeに反映させることも出来るが、最終的にはどうしても以下のようなコードが必要になる。

// ---------- AppController.h ----------
#import <Cocoa/Cocoa.h>

@interface AppController : NSObjec {
    IBOutlet id slider;
    IBOutlet id textField;
}

- (IBAction)updateSlider:(id)sender;
- (IBAction)updateTextField:(id)sender;

@end
// ---------- AppController.m ----------
#import "AppController.h"

@implementation AppController

- (IBAction)updateSlider:(id)sender {
    [textField setObjectValue:[sender objectValue]];
}

- (IBAction)updateTextField:(id)sender {
    [slider setObjectValue:[sender objectValue]];
}

@end

当初は、これでも画期的なコーディング方法と感じていたが、もう何年も前からCocoaBindingが実現されており、今となっては伝統的な(古くさい?)方法になりつつある。問題は、決まりきった上記コードを冗長に書く必要があることだ。

  • もし、スライダーとテキストフィールドのペアが10組あったら、上記コードは10組分必要になる。(実際のデスクトップアプリケーションなんて、あっという間にそれ以上の組み合わせが必要になる。)
  • そして、挙動を修正しようとした時は、上記コードの中から対応するGUIのコードを探し出すことになるのだが、おそらく似たようなメソッドがたくさんあったら、間違い易いだろう。
  • さらに、環境設定としてファイルに保存しておきたいと思った時は、ユーザーデフォルトに対してターゲットとアクションを設定して、
  • その変化をリアルタイムに関係する部分に反映させていと思ったら通知(Notification)を監視して...。

これでは、GUI部品からのデータを取得する、または反映させるためのコードで埋め尽くされてしまう。本来は、スライダーの設定によって何か役立つ情報を出力するのが目的のはずだが、その処理を書く前に疲れ果ててしまう。
この状況を解決するためにCocoaBindingという仕組みが新たに作られて、その結果、劇的に改善されてしまった。GUI部品からデータを取得する、または反映させるためのコードは1行も必要ないという状況に!

CocoaBindingによる方法

  • ウィンドウにスライダーとテキストフィールドを配置する。(スライダーのContinuousはチェックありに)

ここまでの手順は同じ。

  • NSObjectControllerを追加する。
  • CocoaBindingの設定をする。(以下左から、スライダー、テキストフィールド、オブジェクトコントローラーの設定)


    • 細かな設定項目があるが、かなりの部分Interface Builderが良きに計らってくれるので、実際の自分の作業は以下の3つのみ。
      • スライダーのModel Key Pathに「alpha」と入力した。
      • テキストフィールドのModel Key Pathで「alpha」を選択した。
      • オブジェクトコントローラーのPrepares Contentにチェックマークを入れた。


以上で作業完了。本当にコードは1行も書いていない。果たしてこれでコーディングしていると言えるのか?つまり、お決まりのコードは不要になって、有益な情報を出力するロジック部分に自分の全リソースを集中することができるようになったということか。より素晴らしいアプリケーションを短期間で作成する環境は整ったのだ。あとは、人間が頑張らなくては...ね。

作業環境

*1:スライダーを動かしている最中の更新を有効にするため