異なるxibにあるオブジェクト間でのデータ渡し(検討編)
注意事項
前回、Cocoaで複数のウインドウを扱うプログラムを作成した。
しかし、前回のサンプルではウインドウ間でのデータのやり取りをしていない。
ウインドウ間(正確には各xibファイルに配置したオブジェクト間)のデータのやり取りをどう実現すればいいのかは、気付かないとかなり悩む。自分の場合、その方法を記載している(かつ自分の頭でも分かるレベルの分かりやすい)サイトを見つけられず、かなり時間を要した。
結果的にはできたので、ウインドウ間のデータ移動について分かったことをメモする。
■データの受け渡し方法
そもそも異なるxibにあるオブジェクト間のデータ移動で悩んだ原因は、xibごとのオブジェクトが、XcodeのGUI上(Interface Builder)で分離されていたからである。Outletで接続してやりとりでもできれば簡単だが、どうやらGUI操作では別のxibにあるオブジェクト同士に関連性を持たすことはできないらしい(やり方を見つけられなかった)。
つまりコード上でデータ渡しの仕組みを実現する必要がある。
・案1:NSWindowController経由
恐らくまず最初に思い付く、NSWindowControllerサブクラスにデータ受け渡し用のメソッドを用意しておきそのインスタンスに対してデータを渡す方法。
実際に実装していくとNSWindowControllerにデータを持たせるのではなく、別のオブジェクトで管理したくなると思う。なのでNSWindowControllerはデータを渡したいオブジェクトへの中継として使うことが多くなるだろう。
・案2:AppDelegate経由
プロジェクト内のデータ渡しの方法を調べていて知ったのが、AppDelegateを使ったデータ共有。
プロジェクトを作成した時に初めからファイルが作成されているAppDelegateクラスを使う方法である。MacやiPhoneのアプリを普段から作っている人には当たり前の方法かもしれない。
詳しく調べていないが、プログラムを実行する際にAppDelegateインスタンスが1つ作成されるらしい。プログラム内のどのクラスからもそのインスタンスへアクセスできるため、AppDelegateを介してデータのやりとりができる。
・案3:クラス内グローバル変数
クラスの実装ファイルに大域変数(正確にはクラス内局所変数?)として共有したいデータを記載すれば、異なるxibでも同じクラスのインスタンス同士でデータのやり取りができそう。xib間共有クラスとしてアクセサメソッドも用意すれば、利用するクラスに関係なくデータ中継専用のクラスとして活用できると思うので、拡張性もそれなりにある。
クラス内に大域変数を使うこと自体あまりよい設計ではない気がするものの、メンテナンスやリソースに負担がかからない実装ができればありだと思う。
・案4:NSNotificationCenter経由
これは最後の最後に気付いた案。逆に、NSNotificationCenterを知ってる人は一番最初に考えであろう案。
説明の構成上、最後に解説する。
■各案の実装方法
作るプログラムの仕様にもよるが、実装しようとすると、どのみち案1か案2の仕組みを利用しなければならない。恐らく多くのプログラムでは、案2、案3を単独で運用するのは少し難しい。
それぞれの案の実装について、次回の実装編で解説する。