|
|
Log In | Not a Member? |
Contact ADC |
| < Previous PageNext Page > |
ここまで、この章ではCocoaの基礎的なアプリケーションアーキテクチャを中心に解説し、アプリケーションのコアオブジェクトどうしが実行時にどのように連携してイベント処理と描画を円滑にするのかについて説明してきました。しかし、ここでは話題の中心をいくぶん変えて、Cocoaアプリケーションの実行の全体像について説明します。アプリケーションがその起動時に、アプリケーションを構成するすべてのオブジェクトを「何もない状態から」作成するということは、めったにありません。それらのオブジェクトのほとんどとは言わないまでも、その多くは、アプリケーションバンドルの中に、オブジェクトグラフのアーカイブとして格納されています。これらのオブジェクトグラフは、ユーザがアプリケーションを終了する直前の状態のアプリケーションデータをカプセル化する、モデルオブジェクトを表すことができます。または、アプリケーションのユーザインターフェイスを構成するウインドウやビューその他のオブジェクトをエンコードしたものを表せます。アプリケーションは、実行時にオブジェクトアーカイブをロードして展開し、元のオブジェクトを再作成します。
アプリケーションバンドルには、オブジェクトやコードだけでなく、それ以外の画像やローカライズ文字列などのリソースも含まれています。このセクションでは、あらゆる種類のアプリケーションリソース(ローカライズされたものとローカライズされていないものの両方)を検索してロードする際にNSBundleクラスのインスタンスが果たす役割について、その概要を説明します。
オブジェクトのアーカイブ
nibファイル
アプリケーションリソースのロード
プログラム内のオブジェクトは、ほかのオブジェクトとの関係を表すネットワークの中に存在します。オブジェクトは、特定のオブジェクトまたはオブジェクトのコレクションを所有したり、ほかのオブジェクトに依存したり、あるいはプログラム内のオブジェクトにメッセージを送信するためにそれらのオブジェクトへの参照を持っていたりできます。このように互いに関連し合うオブジェクトどうしの関係を表現したものを、オブジェクトグラフと呼びます。オブジェクトグラフは非常に複雑になる場合があります。
オブジェクトグラフを格納するための手段となるのがアーカイブです。通常、アーカイブはファイルの形式をとりますが、プロセス間で送受信されるストリームにすることもできます。アーカイブでは、グラフ内の各オブジェクトの識別情報、および、グラフ内での、あるオブジェクトとほかのすべてのオブジェクトとの関係がすべて維持されます。また、アーカイブでは、各オブジェクトの型がオブジェクトのデータと一緒にエンコードされます。オブジェクトグラフが展開されるときにデコードされる各オブジェクトは、通常は最初にストリームにエンコードされたときのオブジェクトと同じクラスになります。また、オブジェクトのインスタンスデータもデコードされ、オブジェクトの再構築に使用されます。グラフ内のオブジェクトどうしの関係も復元されます。その結果、展開されたグラフはほとんど常に、元のオブジェクトグラフを複製したものになります。
注: Cocoaアプリケーションの多くでは、各自のモデルオブジェクトの永続ストアとしてアーカイブを使用しています。しかし、Core Dataフレームワーク(Cocoaフレームワーク)では、より洗練されたメカニズムを使用してオブジェクトの永続性を確保しています。詳細については、“「Cocoaのその他のアーキテクチャ」”(この文書内)、および『Core Data Programming Guide』を参照してください。
アーカイブするということは、オブジェクトグラフ内の各オブジェクトに対してオブジェクト自身をストリームにエンコードするように要求する操作です。一方、展開はその逆で、各オブジェクトに対してオブジェクト自身をデコードするように要求する操作です。どちらの操作も、グラフのルートオブジェクトにメッセージを送信することによって開始されます。アーカイブに保存する必要のあるオブジェクトは、要求された時点で自身をエンコードする必要があります。また、復元を可能にするため、自身をデコードできる必要があります。Cocoaにはシーケンシャルとキー付きの2種類のアーカイブ方法があります。それぞれ、オブジェクトのエンコードおよびデコードの異なるスタイルを反映します。シーケンシャルアーカイブでは、オブジェクトが自身のインスタンスデータを同じ順序でエンコードおよびデコードする必要があります。キー付きアーカイブ(より先進的なアプローチ)では、格納対象の個々のインスタンスデータを、キー(識別文字列)を使用して格納および取得することができます。自身のインスタンスをアーカイブする必要のあるクラスは、NSCodingプロトコルに準拠する必要があります。シーケンシャルアーカイブを実行するオブジェクトでは、NSCoderクラスのエンコードメソッドとデコードメソッドを使用します。キー付きアーカイブ(および展開)では、NSKeyedArchiverクラスおよびNSKeyedUnarchiverクラスのメソッドを使用する必要があります。
参考資料: オブジェクトのアーカイブと展開に関する詳細については、『Archives and Serializations Programming Guide for Cocoa』を参照してください。
Cocoa開発者のほとんどは、Interface Builderアプリケーションを使用してアプリケーションのユーザインターフェイスを構築します(Interface Builderを必ずしも使用しなければならないわけではありませんが、開発者の作業がきわめて楽になります)。以前の章でも紹介しましたが、Figure 6-22に、Interface Builderの典型的なウインドウ配置を示します。ユーザインターフェイスを作成するには、テキストビューやボタン、テーブルビューなどのオブジェクトをパレットからドラッグし、ウインドウにドロップします。そして、オブジェクトの位置やサイズその他の属性を設定します。また、これらのオブジェクト間で各種の接続(アウトレット、ターゲット/アクション、バインディング)を作成することもできます。Interface Builderでは、カスタムのモデルまたはコントローラクラスの初期定義を行い、それらのクラスのプロキシインスタンスへの接続、およびプロキシインスタンスからの接続を、作成することもできます。さらに、Interface Builderを使用して、NSViewのカスタムサブクラスに割り当てるプレースホルダオブジェクトを指定することもできます。Interface Builderでのユーザインターフェイスに関する作業を終えたら、ユーザインターフェイスをプロジェクトのnibファイルに、ローカライズされたリソースとして保存することができます。nibファイルはプロジェクトのビルド時に、アプリケーションバンドル内の同じローカライズ(.lproj)フォルダにコピーされます。
nibファイルは、そのオブジェクトグラフがユーザインターフェイスの一部分または全体を記述するアーカイブです。これらのグラフはユーザインターフェイスの中の複雑な関係を表します。たとえば、ウインドウのビュー階層や、オブジェクト間の各種のつながりなどを表します。これらのオブジェクトグラフの記述には、表現言語としてXMLが使用されています(nibファイル内のXMLを直接編集することは避けてください)。
グラフのルートオブジェクトはnibファイルウインドウの「Instances」ペイン(Figure 6-22で左下にあるウインドウ)に表示されます。この例では、Panelインスタンスがルートオブジェクトです(ビュー階層を含んでいるため)。nibファイルには、ほかのルートオブジェクトに加え、NSControllerオブジェクト(バインディングに使用されます)や、カスタムクラスのプロキシインスタンスを持たせることもできます。また、Cocoaアプリケーションの各nibファイルウインドウには以下の2つの特殊なインスタンスがあります。
File's Owner。nibファイルを所有し、その中のオブジェクトを管理するオブジェクトです。File's Ownerはnibファイルの外部に存在する必要があります。File's Ownerオブジェクトは、nibファイル内のオブジェクトとnibファイル外のオブジェクトとを接続する伝達路として使用します。
First Responder。レスポンダチェーン内の最初のレスポンダを表すオブジェクトです(“「レスポンダとレスポンダチェーン」”を参照)。ターゲット/アクションの接続では、First Responderをターゲットとして指定できます。コントロールまたはメニューからアクションメッセージが送信されると、そのメッセージを処理することのできるオブジェクトが見つかるまで、アプリケーションがレスポンダチェーン内を検索します(検索はFirst Responderから開始します)。
Interface Builderのパレットにある標準のオブジェクトは、ユーザインターフェイスを構築するときに割り当てと初期化が行われ、後でオブジェクトがnibファイルに保存されるときにアーカイブされます。nibファイルが展開されると、これらのオブジェクトが復元されます。標準のパレットオブジェクトのクラスをベースとするカスタムサブクラスを作成した場合は、Interface Builderによって、オブジェクトのアーカイブ時にそのスーパークラスがエンコードされますが、オブジェクトの展開時にはカスタムクラスが入れ替えられます。どちらの場合も、展開されたオブジェクトのイニシャライザは呼び出されません。ただし、NSViewのカスタムクラス(Custom Viewパレットオブジェクトによって表されます)がある場合は、Custom Viewオブジェクトの展開時にそのクラスのイニシャライザが呼び出されます。いずれの場合も、nibファイル内のすべてのオブジェクトの展開が完了した時点で、アプリケーションから、nibファイルに関連付けられている各カスタムクラスに対して、awakeFromNibメッセージが送信されます。このメッセージによって、接続の確立やその他の準備作業を実行するための機会がクラスに与えられます。
Cocoaアプリケーションはそれぞれメインnibファイルを持ちます。メインnibファイルには、アプリケーション固有メニューが格納されています。また、1つ以上のウインドウが格納されている場合があります。NSAppは、メインnibファイルに対するFile's Ownerです。アプリケーションが起動すると、NSAppによってメインnibファイルがロードされて展開され、メニューと初期状態のウインドウが表示されます。アプリケーションの多くは、ドキュメントやパネルのための補助のnibファイルを持っています。これらのnibファイルは必要に応じてロードされます(つまり、nibファイル内のオブジェクトによって提供される動作をユーザが要求した時点でロードされます)。
nibファイルは、画像ファイルやサウンドファイル、ヘルプファイルその他のデータと同様に、アプリケーションリソースです。アプリケーションリソースはローカライズが可能です。つまり、複数の言語やロケールに対応させることができます。nibファイルのローカライズは、ユーザインターフェイスに表示される文字列の翻訳が主体になりますが、それ以外の変更が必要になる場合もあります。たとえば、新しい文字列に合わせて、テキストフィールドやボタンその他のユーザインターフェイスオブジェクトのサイズを変更しなければならない場合があります。日付や数値の形式を変更しなければならない場合もあります。
国際化という言葉は、ローカライズをサポートする開発インフラストラクチャを表します。ソフトウェア製品を国際化する際には、言語やロケールに対応したリソースを、バンドルのResourcesディレクトリ内部の特定の場所に格納する必要があります。この格納場所は、言語(そして場合によってはロケール)を識別する名前を持ったフォルダです。名前は、周知の言語指定文字列か、あるいはISO 639-1、ISO 639-2、および(ロケールの場合)ISO 3166-1の各規格に準拠した省略形のどちらかです。ローカライズフォルダの拡張子は.lprojです。ユーザはシステム環境設定の「言語環境」ペインで言語の優先順位リストを作成します。そしてアプリケーションは、この設定に最初に一致する言語に対応した.lprojフォルダからリソースを選択します。Xcodeではアプリケーションリソースの国際化がサポートされています。.lprojフォルダを含むバンドル構造が作成され、アプリケーションリソースが自動的に設定されます。
アプリケーションリソースを非ローカライズにすることもできます。非ローカライズのリソースは、アプリケーションバンドルのResourcesディレクトリの直下に格納され、.lprojディレクトリの外部に置かれます。
実行時に、アプリケーションはバンドルの中でアプリケーションリソースを探し出し、メモリにロードすることができます。この目的のために、アプリケーションはNSBundleクラスのインスタンスを使用します。このクラスのメソッドは、リソースの名前と拡張子を指定されると、該当するリソースへのファイルシステムパスを返します。Application KitのNSBundleのカテゴリをアプリケーションで使用することで、nibファイル、ヘルプファイル、サウンドファイル、画像ファイルなどを探し出してロードすることができます。たとえば、NSBundleクラスのメソッドloadNibNamed:owner:は、指定された名前を持ち、参照されたオブジェクトによって所有されているnibファイルを検索してロードします。この方法でリソースを動的にロードするプログラミングを実践することで、アプリケーションの全般的な効率が高まります。アプリケーションでは、ユーザから要求があったときにのみリソースをメモリにロードするようにしてください。
アプリケーションでは、ファイルベースのリソース以外のリソースも動的にロードできます。ローカライズされた文字列を、プログラムから特定のコンテキスト(たとえば、表示されるメッセージが変化する可能性のあるダイアログなど)に応じてロードできます。ローカライズされた文字列は、バンドルの.lprojディレクトリの1つに格納されている「strings」ファイル(拡張子が.stringsのファイル)から取得されます。アプリケーションのメインバンドルにはロード可能バンドルと呼ばれる補助的なバンドルを格納することもできます。ロード可能バンドルには独自のコード(およびリソース)を格納でき、アプリケーションからはNSBundleオブジェクトを使用してそのコードを動的にメモリにロードできます。ロード可能バンドルは、一種のプラグインアーキテクチャを通じてアプリケーションの動作を柔軟に拡張することを可能にします(このアーキテクチャの一例としてAutomatorアプリケーションがあります。Automatorでは、ロード可能バンドルであるアクションを動的にロードします)。
参考資料: ローカライズと国際化の詳細については、『Internationalization Programming Topics』を参照してください。NSBundleとバンドルの詳細については、『Loading Resources』および『Dynamically Loading Code』を参照してください。
| < Previous PageNext Page > |
Last updated: 2006-05-23
|
Get information on Apple products.
Visit the Apple Store online or at retail locations. 1-800-MY-APPLE Copyright © 2007 Apple Inc. All rights reserved. | Terms of use | Privacy Notice |