● Carbon視点でCocoa探求(2007/10/17)

  このニュースは、MOSAの会員にのみ配布されているデベロッパー向けの
  デジタルマガジンMOSADeNのに掲載された記事です。ほぼ一ヶ月遅れで
  ここに掲載されて行きます

 〜 Cocoa新規プロジェクトの中身 〜


今回は、テンプレートから作成した「Cocoa Application」と「Cocoa Document-based Application」の新規プロジェクトフォルダの中身を、Carbonプロジェクトの場合と比較しながら調べてみることにします。

まず最初に、Cocoa Applicationプロジェクトの内容を調べてみます。新規作成したプロジェクトの名称は「Cocoa_Test」とします。これにより、プロジェクトに必要なファイルは、すべてCocoa_Testフォルダ内に保存されます。

Cocoa_Test.xcodeprojはプロジェクトファイル(ドキュメント)自身です。これをダブルクリックすることでXcodeが起動し、対応するプロジェクトウィンドウがオープンされます。Buildフォルダには、登録ファイルのリンク関係、コンパイル後のオブジェクトファイル、Makeされた実行ファイル(アプリケーション自身)などが保存されることになります。このフォルダは削除しても、次回にプロジェクトをオープンする時に再度作成されます。よって、プロジェクトに登録しているファイルのリンク関係が壊れてMake時にエラーが出るよう場合、このフォルダを削除してやれば直ることがあります。

Cocoa_Test_Prefix.pchファイルはプリコンパイルされるソースファイルであり、一般的にはプリコンパイルしておきたいヘッダファイルを記述しておくのが普通です。Carbonのデフォルト記述は#include <Carbon/Carbon.h>ですが、Cocoa_Test_Prefix.pchでは以下のように記述されています。

#ifdef __OBJC__
    #import <Cocoa/Cocoa.h>
#endif

これにより、Cocoa.hの内容がプリコンパイルされることで、2回目からのLink処理の速度を上げることが出来ます。不思議なことに、Carbonの場合にはビルドオプションのコンパイラ設定で「プレフィックスヘッダをプリコンパイルする」オプションをONにし、「プレフィックスヘッダ」に、そのファイル名(例えばCaarbon_Test_Prefix.pch)を記述しておかないとダメなのですが、Cocoaプロジェクトでは、そのオプションはOFFのままでファイル名も記述されていません。しかし、これでもちゃんとプリコンパイルされているようなのです?謎ですね。

ところで、Cocoa.hの中身は以下のような記述となっています。

#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <CoreData/CoreData.h>

このためプロジェクトのFrameworksグループには、ヘッダ名に準拠した4つのFramework(Cocoa.framework,AppKit.framework,CoreData.framework,Foundation.framework)が登録されています。

もし、ソースコード内でQTKitやQuartzComposerなどの最新機能を使いたい場合には、プロジェクトにそれらを含むFreameworkを追加登録し、ソースファイルの必要箇所に関連ヘッダファイルを記述しておく必要があります。例えば、QTKitを使いたい時は、Xcodeのプロジェクトメニューの「プロジェクトに追加...」でプロジェクトのFrameworksグループにQTKit.frameworksを登録し、それを必要とするソースファイルの先頭には#import <QTKit/QTKit.h>を記述します。ちなみに、こうしたFrameworkが保存されている場所は、システムフォルダに含まれるライブラリフォルダ内のFrameworksフォルダ内です。

English.lprojフォルダの内部には、InfoPlist.stringsとMainMenu.nibの2つのファイルが含まれています。InfoPlist.stringsは、アプケーション情報のローカライズされた文字列が記述されています。ディフォルトでは、以下のようにアバウト表示に用いるコピーライトのみが含まれています。

NSHumanReadableCopyright = " __MyCompanyName__, 2007";

この文字列の内容を変更すると、アバウトに表示される文字列も自動で切り替わります。余談ですが、Carbonの場合には、何故だかこの文字列がアバウトに表示されません。バグでしょうか?

MainMenu.nibは、アプリケーションで用いられるメインNibファイルです。Carbonプロジェクトのmain.nibと同じ意味合いを持っています。このNibファイルの内容については次回に詳しく解説したいと思います。

English.lprojフォルダには英語にローカライズされた文字列ファイルやNibファイルを保存しておきます。別途日本語用ローカライズファイルを用意した時には、Japanese.lprojフォルダを作り、その中に必要なファイルを入れておきます。こうしたフォルダは、その後アプリケーション・パッケージのResourcesフォルダ内に複製されることになります。また同様に、アプリケーションで用いるアイコンや画像ファイルもResourcesフォルダに複製されますので、最終的にパッケージのResourcesフォルダには相当数のファイルが保存されるケースが出てきます。

こうしたことから、筆者は、先んじてプロジェクトフォルダ(今回はCocoa_Testフォルダ)内にResourcesフォルダを作り、その中にEnglish.lprojを入れてプロジェクトに再登録しています。同様にJapanese.lprojフォルダやアイコン、画像ファイルを使う時も、そのResourcesフォルダに保存しておきます。こうすれば、パッケージのResourcesフォルダ内に保存されるファイルは、すべてプロジェクフォルダのResourcesフォルダ内と一対一で対応していることになり、プロジェクトのファイル構成が分かり易くなります。

inof.plistは、作成するアプリケーションに必要な各種情報が記載されているXMLファイルです。この内容は、プロジェクトウィンドウのターゲットアイコン(Cocoa_Test)をダブルクリックすることで表示される「ターゲット"Cocoa_Test"の情報」パネルの「プロパティ」タブに示される内容と同等です。ですから、inof.plistを編集する必要がある場合には、直接ではなくこちらのパネル経由で操作すれば良いことになります。

main.mは唯一のソースファイルです。Objective-C用ソースファイルの拡張子は.cではなく.mである必要があります。記述内容は、以下の通りで、main()でNSApplicationMain()を呼び出しているだけです。

int main(int argc, char *argv[])
{
    return NSApplicationMain(argc, (const char **) argv);
}

Carbonで言えば RunApplicationEventLoop()を呼び出しただけのような感じですね。しかし、Carbonアプリケーションの場合にはそれだけでは何も起こりません。メニュー用のNibファイルを呼び出したり、アプリケーション用のCarbon Event Handlerを登録したりする必要があります。また、main.nibに登録されているウィンドウを実際にオープンするためにも、それなりの手続きを記述してやる必要があります。

それと比較してCocoaの場合には、これだけの記述でMainMenu.nib内の各オブジェクトをインスタンス化し、適切なイベントコマンドとアクションのリンクまで行います。その結果としてNibファイルに登録されているウィンドウがオープンされ、メインメニューに記述されてるコマンドも認識されるアプリケーションが完成します。つまりCarbn用のプロジェクトのmain.cに記述されている処理内容を、すべてCocoa Framewok側が受け持ってくれていると考えれば良いわけです。

続いてCocoa Document-based Applicationプロジェクトの方を調べてみます。新規作成したプロジェクトの名称は「Cocoa_Doc」とします。Cocoa Applicationプロジェクトとの違いは、English.lprojフォルダ内にCredits.rtfとMyDocument.nibが追加されていることです。Credits.rtfにはアバウト表示での追加情報が記載されており、MyDocument.nibには、ドキュメントとしてオープンさせるべきウィンドウなどのオブジェクトが登録されています。また、MyDocumentクラス(NSDocumentクラスを継承)を記述した、MyDocument.hとMyDocument.mの2つのソースファイルも追加されています。プロジェクトフォルダ内の違いはたったこれだけです。

CocoaアプリケーションでのNibファイルの役割は、Carbonのそれとは大きく異なります。Cocoa Frameworkを用いると、ソースコードをあまり記述しなくても色々な処理がこなせるようになります。その理由のひとつがNibファイルの仕組みにあります。次回は、今回登場した2つのNibファイル、MainMenu.nibとMyDocument.nibの内容を詳しく調べてみたいと思います。

copyright 2007 Ottimo, Inc. All rights reserved
無断転載・引用禁止