MOSA Multi-OS Software Artists

MOSAはソフトウェア開発者を支援します

プログラマーに興味がある方なら誰でも入会いただけます。
MOSA Multi-OS Software Artists
===SINCE 1995===

  • iPhone/iPod touch アプリ紹介
  • MOSA掲示板
  • 活動履歴
  • About MOSA(English)

MOSADenバックナンバー 2004年1月発行分

  • MOSA Developer News[MOSADeN=モサ伝]第98号

    2004-01-27

    目次

    • Cocoaでいこう! Macらしく  第36回  Yoshiki(DreamField)
    • 小池邦人の「Carbon API 徒然草」
    • 「Behind the WebObjects」  第12回  田畑 英和
    • ニュース・解説
    • MOSAからのお知らせ

    Cocoaでいこう! Macらしく  第36回 Yoshiki(DreamField)

     前回説明したように、実際にプログラムを組む時には色々と考慮すべきことがあります。今回は、説明を分かりやすくするために、あえて手を抜いて説明から除外していた部分で、しかしプログラムを組む上では考慮しておいた方が良いことを説明します。

    オブジェクトをセットするメソッドで気をつけるべきこと

     MyImageViewクラスでは、イメージをセットするメソッドを次の様に実装していました。

    - (void)setImage:(NSImage *)newImage{
        image = newImage;
        [ image retain];
        [ self setFrameSize: [ image size]];
    }

    実はこれはあまり良い実装ではありません。どこがまずいのかと言うと、2回以上呼び出されることを考慮していないからです。
     確かに今回のプログラムでは、2回呼び出されることはありません。しかし、将来どんな改良を加えることになるか分かりませんし、他のプログラムに流用するかもしれません。あるいは、バグによって2回以上呼び出されることだって考えられます。従いまして、どの様な使われ方をしても、妥当な動作をする様に組んでおくことが、将来に渡って問題を起こしにくくするコツであると言えます。
     では、このメソッドが2回以上呼び出されたら、何が起こるのか考えてみましょう。1回目は、imageに新しいイメージへのポインタがセットされ、retainすることにより所有することになります。2回目も、imageに新しいイメージへのポインタがセットされ、retainすることにより所有します。プログラムの動作上、特に問題は起こりません。しかし、良く考えてみて下さい。1回目に受け取ったイメージはどうなってしまったのでしょうか。自分がretainしたのですから、自分でreleaseする義務があります。ところが、このプログラムではこれを行っていません。つまり、1回目にセットしたイメージは、既に必要無いのに、プログラムが終了するまで所有しっぱなしです。この様に、2回以上呼び出されると、メモリリークを起こしてしまうのです。
     これを防ぐためには、既にセットされているイメージをreleaseしてから、新しいイメージをセットする必要があります。そこで次の様に実装してみましょう。

    - (void)setImage:(NSImage *)newImage{
        [ image release];
        image = newImage;
        [ image retain];
        [ self setFrameSize: [ image size]];
    }
    


     このプログラムはimageをreleaseしてから、新しいイメージをセットしています。こうすれば、前回セットしたイメージが残ってしまうことを防げます。では、1回目に呼び出された時はどうなるでしょうか。1回目は、イメージがセットされていないのに、releaseメッセージを送ってしまっています。ですが、これは問題になりません。何故なら、クラスを生成した時に、全てのインスタンス変数は0クリアされており、imageの値はnilだからです。nilにメッセージを送っても、何も起こりません。
     さて、これで一見問題は無いように見えます。ですが、実はこれでもまだ駄目なのです。どんな時に駄目なのかと言うと、2回以上連続で同じイメージをセットしようとした時です。どうなるのか考えてみましょう。1回目はimageはnilですから、releaseメッセージを送っても何も起こりません。そしてimageに新しく渡って来たイメージのポインタがセットされ、retainして所有します。2回目は、imageには前回セットしたイメージへのポインタが入っています。releaseメッセージを送れば、このイメージは解放されます。そして、今解放したのと同じイメージへのポインタをimageにセットし、これにretainメッセージを送って・・・。ちょっと待って下さい。解放してしまったイメージにretainメッセージを送ったら、このプログラムは誤動作してしまいます(おそらくは吹っ飛びます)。そもそも、一度解放して消えてしまったイメージを、今更所有なんて出来ません。つまり、まったく同じイメージを2回以上連続でセットすると、吹っ飛ぶという、とても危険なプログラムになってしまったのです。
     それでは、このことも考慮した実装にしましょう。

    - (void)setImage:(NSImage *)newImage{
        NSImage *tmpImage;
    
        tmpImage = image;
        image = newImage;
        [ image retain];
        [ tmpImage release];
        [ self setFrameSize: [ image size]];
    }
    


     imageの値を退避しておき、後で使えるようにした上で、imageに渡って来たイメージのポインタをセットしています。そして、こちらを先にretainし、その後で退避していた値を使って、今まで所有していたイメージをreleaseしています。この様にすれば、同じイメージが来ても、先にretainしていますから、releaseしても解放されません。違うイメージの場合でも、それぞれに対してretain、releaseしていますから問題は起こりません。とてもシンプルな方法です。
     もう一つの書き方を紹介しましょう。私は普段、こちらの書き方で組んでいます。

    - (void)setImage:(NSImage *)newImage{
        [ newImage retain];
        [ image release];
        image = newImage;
        [ self setFrameSize: [ image size]];
    }
    


     まず、新しいイメージをretainしてしまいます。それから、今までセットされていたイメージをreleaseします。そして、その後imageに新しいイメージへのポインタを格納します。この例の場合も先ほどと同様、新しいイメージのretainを先に行っていますから、たとえ同じイメージが来たとしても、releaseで解放されません。違うイメージの場合も、それぞれに対してretain、releaseしているのですから、大丈夫です。imageに格納するのはあくまでポインタであって、オブジェクトそのものではありませんので、この様な書き方も出来るわけです。

    小池邦人の「Carbon API 徒然草」(2004/01/23)

    プログラミングを楽しむために

    Carbon API 徒然草の連載は2002年7月から始まりました。およそ1年半にわたり、Carbon Frameworkに巣くう(笑)個性的なAPIをいくつか紹介してきたわけです。Framework内のAPIが個別にどんな機能を有しているかを知ることはとても大事です。この点は、CarbonだけでなくCocoaや別のFrameworkについても言えることでしょう。しかし、アプリケーションを開発していると、API個々の能力を知るだけではうまくいかないケースに遭遇します。アプリケーションでは、いくつものAPIが有機的に結びつくことでひとつの機能を実現しています。またそうした機能が再度結びつくことで、より大きな仕組みをユーザに提供することになります。

    API個々やそれを使った関数を勉強することが単語や文章の記述を身につけることに相当するならば、アプリケーション開発は、ひとつの小説を執筆することに相当するのかもしれません。また、アプリケーションを開発する時には、それを使う「ユーザ」、つまり小説に対する読者の存在を考慮に入れる必要もあります。実際にやってみないと分からない、もしくは理解できない色々な問題にも遭遇することにもなります。そこで、Carbon API 徒然草も本年から「実践編」ということで、一本のちゃんとしたアプリケーションを開発する過程をたどりながら、その中で登場してくるAPIの有機的なつながりや仕組みを解説していきたいと思います。

    今回、実践編のサンプルとして利用するのは「2003年MOSA湘南セミナー」でCarboとCocoaの比較に利用した「MOSA_Sample_Carbon版」です。実際のセミナーは非常に短い時間でしたし、参加された方にも限られた解説しかできませんでしたので、それを補う意味でもこのサンプルを選んでみました。サンプルアプリケーションは「MOSA2003_Sample.sit」という名称で、筆者のサイトにアップされています。

    http://www.ottimo.co.jp/library/index.html

    利用している開発環境は、Metrowerks CodeWarrior 8.3ですが、ソースやリソースをそのまま移動すれば、Xcodeでも利用できると思います。当然CodeWarrior 9.0や 9.1でも問題ありません。ライブラリやヘッダファイルの保存場所アクセスパスに関して何か問題が生じた場合には、ご自分の環境に合わせてパスを変更してご利用ください。また、プリコンパイルドヘッダの名称などにもご注意ください。

    このサンプルアプリケーションは、Carbon FrameworkとNibファイルによるコラボレーションにより開発されています。Carbonも、Nibファイルとの連動、Carbon Eventの実装、HIObject、HIViewの登場などにより、そこそこ(笑)モダンなFramewrokへと変貌しています。そうした最近の成長をあまり体験されていない方にとっては、この期にもう一度Carbonを見直してみても良いかもしれません。開発言語には「ピュアC」を利用しC++は使いません。ソースコード内で使うCの文法表記も、if、else、while、for、switch、case、break、returnに限ります。言語、環境、概念などの難しい話は抜きにして、純粋に「プログラミング」という行為を楽しみたいと思います。

    また、現状のソースコードをそのまま解説して行くのも芸がないので、サンプルのReadmeにも記載されていますが、タイミングを見計らって以下のような機能をアプリケーションに追加してみたいと思います。もちろん、途中で面白いアイデアが湧いてくれば、そちらを優先してインプリメントするかもしれません。本線から脱線していくのがプログラムの楽しみ方のひとつですので…(笑)

    ・アプリケーションの初期設定の保存
    ・ウィンドウ(ドキュメント)設定の保存
    ・ファイルからの復帰、別名保存
    ・ページ設定、プリントダイアログ
    ・データブラウザ内のアイテムの順序変更
    ・アイテムからFinderへのドラッグ&ドロップ
    ・ウィンドウに表示した画像のカット&ペースト
    ・矢印キーによる選択アイテムの移動
    ・ダイアログやアラートのシートウィンドウへの対応
    ・ファイル保存を構造体のサイズに依存させない
    ・長いファイル名に対応させるためFSSpecをFSRef対応に変更
    ・上記にからんでユニコード文字列への対応

    最近のプログラミングと言うと、言語に縛られ、APIに縛られ、Frameworkに縛られ、開発環境に縛られ、プログラミング概念に縛られ(笑)…どうも、筆者がBASICを使い徒然なるままに、好奇心のおもむくままに、創造の世界に浸っていたころの楽しさがなくなってしまったような気配です。まあ楽しいばかりでは仕事にならないという現実も存在しますが(笑)もう少し「気軽な体験」としてのプログラミングが戻ってきてくれればと思う今日この頃です。Macintosh用のアプリケーションを開発しながら、思いつくまま新しいアイデアをどんどん実現してみましょう!プログラミングが本来もっている、積み木で遊んでいるような「創造の楽しさ」を共有できればと考えています。

    「Behind the WebObjects」  第12回  田畑 英和

     前回はD2Wのルールについて解説しましたがいかがでしたでしょうか。D2Wではルールを記述することによりアプリケーションの挙動を定義していくことができます。ですが、いきなりルールを直接記述していくのはハードルが高いとおもいますので、以前紹介したアシスタント機能を使ったアプリケーションのカスタマイズ方法についてみていきたいと思います。

     アシスタント機能を用いればGUI上である程度のカスタマイズができますが、背後ではアシスタント上での設定に応じて自動的にルールの生成がおこなわれています。つまり間接的にルールを生成していることになるわけですが、このようにして自動生成されたルールを応用することにより、さらに作り込をおこなっていくこともできます。
     まずアシスタントの画面構成ですが、”Standard Mode”と”Expert Mode”の2つに分かれており、”Expert Mode”ではより細かい設定ができるようになっており、ページのGeneration機能が利用できます。どちらのモードを用いる時も基本的には1ウィンドウのシンプルな形式になっており、いくつかの機能がタブによって分けられています。

    ・”Entities”タブ

     Entityはデータベース上では「テーブル」に相当します。この画面ではアプリケーションの処理対象に、プロジェクトに登録済みのモデルで定義されている各Entityを含めるかどうかを設定することができ、指定方法としては以下の3種類があります。

    Hidden Entity:Entityをアプリケーションの処理対象から外します。
    Read-Only Entity:Entityを処理対象に含めますが編集不可にします。
    Read-Write Entity:デフォルトの設定であり、データの編集が可能です。

     アシスタント上で設定をおこなった場合、「Save」ボタンで設定内容を実際にルールに反映させることができます。このときアプリケーションは動作させたままの状態でよく、アシスタント上での変更内容は直接起動中のアプリケーションに反映され、すぐに変更結果を確認することができます。「Save」をおこなう前であれば「Revert」ボタンにより変更をキャンセルすることができます。変更の保存をおこなった後にルールファイルを開いてみると、ルールが追加されていることが確認できます。Entityの設定をおこなったときには以下のようなルールが追加されます。

    Lhs = *true*
    Rhs Key = readOnlyEntityNames
    Rhs Value = (Movie, MovieRole)

    Lhs = *true*
    Rhs Key = visibleEntityNames
    Rhs Value = (Movie, MovieRole, Talent)

     ”Entities”タブでの設定は全画面に反映されますので、ルールを適用する条件のLhsは”*true*”になっています。Rhsですがkeyが”readOnlyEntityNames”のルールではRead-Onlyに指定したEntityの名前がValueに設定されています。またkeyがvisibleEntityNamesのルールにはRead-OnlyとRead-Write両方のEntityのEntity名一覧がValueに設定されています。

    ・”Properties”タブ

     ここではアプリケーションの各画面についてのプロパティを設定します。例えば”Movie”テーブルの検索をおこなう画面をアシスタント上で設定するとします。このとき検索対象に含める”Movie”テーブル上のアトリビュート(カラム)や表示順をプロパティとして設定することができます。また”Movie”テーブル上のアトリビュートだけでなく、リレーション先のテーブルのアトリビュートも検索対象として指定することができます。
     検索対象として、”Movie”テーブル上の”category”と”title”の2つのアトリビュートと、リレーション(studio)先の”name”を指定した場合には次のようなルールが生成されます。

    Lhs = ((task = ‘query’) and (entity.name = ‘Movie’))
    Rhs Key = displayPropertyKeys
    Rhs Value = (category, title, stdio.name)

     今回は特定のページでの処理を指定していますので、Lhsの指定もおこなわれています。ここで”task”の指定がおこなわれていますが、これはD2Wであらかじめ定義されている処理の種類を指定するキーです。検索処理に関するルールを定義しましたので、ここでは”task”が”query”として設定されています。
     ”entity.name”は名前のとおり処理対象のEntity名を指定するキーであり、ここでは”Movie”が指定されています。このようなルールが定義されていたときに”Movie”テーブルに対して検索処理がおこなわれると、D2Wエンジンがこのルールを解釈して、Rhsの”displayPropertyKeys”で指定されたアトリビュートを使用した検索用の画面を生成します。つまり「”Movie”の”query”を行うときには、category, title, stdio.nameの3つを使用します」といった意味のルールが設定されたわけです。

    ・”Page”タブ

     ページのバックグラウンドカラーなど、ページの外見に関するパラメータを設定することができます。またD2Wではあらかじめ処理の内容ごとに数種類のページテンプレートが用意されており、ここで使用するテンプレートの切り替えをおこなうこともできます。テンプレートはあらかじめ用意されているだけでなく、自作してそちらを使用することもできます。
     例えば、”Movie”テーブルを検索した結果を表示するページのテンプレートを別のものに設定した場合以下のようなルールが生成されます。

    Lhs = ((task = ‘list’) and (entity.name = ‘Movie’))
    Rhs Key = pageName
    Rhs Value = BASPlainListPage

    ニュース・解説

     今週の解説担当:新居雅行

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃WebObjectsの講習会。Javaを使わないセミナーと入門・初級向け
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    テクニカルピットは、倉橋浩一氏によるWebObjectsの講習会を次の予定で開催する。
    2004年2月24〜26日は、「JavaなしWebObjectsセミナー」(受講料40,000円)として、Javaの知識がないような開発者や利用者に向けて、WebObjectsを使ったデータベース処理を伴うWebアプリケーションを開発する方法を解説する。2004年3月15〜16日は「WebObjects 5.2 入門セミナー」(受講料30,000円)として、WebObjects初心者向けのツールの利用方法や動作原理などを解説する。
    2004年3月17〜19日は「WebObjects 5.2 初級セミナー」(受講料50,000円)として、リレーションを含むようなデータベース利用やユーザインタフェースを作成する方法などを説明する。

    入門セミナーと初級セミナーを連続受講する場合は受講料が6万円に割引となる。また、いずれのコースも通常3万円の自習用教材Homeworkパーソナル・ライセンス版を1万円で購入することができる。いずれも、自身の機材を持ち込んでの受講が可能であるが、機材をレンタルして利用する事もできる。

    テクニカルピット:WebObjectsのページ
    http://www.techpit.co.jp/WO/

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃Javaによるプロセスを「ヘッドレスモード」で動かす
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Technical Q&Aで、Javaでバックグランドプロセスを稼働させたとき、Dockにアイコンが出てきてしまう問題を解消する方法が掲載された。Javaのプロセスを動かしたとき、その中でAWTを利用すると、そこでCocoaのイベントループが動き出して、現在ログインしているユーザのDockにアイコンが出てきてしまう。場合によってはそこでプロセスを止められてしまう。Java 1.4ではヘッドレスモードとしてユーザに何も見せないで稼働させる事が可能で、システムプロパティのjava.awt.headlessをtrueにして稼働させるという手段がある。
    ヘッドレスモードは、オリジナルのJavaでサポートしているモードである。

    QA1328: Server Processes and the Dock
    http://developer.apple.com/qa/qa2001/qa1328.html

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃Core AudioのMusicPlayerとその接続先
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Technical Q&Aに、Core AudioのMusicPlayerの利用方法についての文書が掲載されている。エンドポイントやディスティネーションの設定を、MusicPlayerにシーケンスを設定した直後に行わないといけないことが解説されている。

    QA1330: Music Player Sequence Destinations
    http://developer.apple.com/qa/qa2001/qa1330.html

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃Mac OS Xネイティブなリソースエディタ
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    The La Jolla Undergroundからリリースされた「ResFool 1.0」は、Mac OS Xネイティブのリソースエディタだ。リソースフォークを開き、タイプごとにリソースを表示し、追加や修正などができる。16進数表示だけでなく、タイプごとに用意されたテンプレートの機能により、システム定義の設定などは、データに合わせた編集作業ができるようになっている。惜しいのは日本語文字列が化けてしまう事であり、フォント設定を変えても化けるので、その点は使いにくい面もある。データフォークに保存するリソースにも対応する。価格は$19.50のシェアウエアとなっている。

    ResFool 1.0
    http://www.ljug.com/sw/resfool.html

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃ファイルメーカーProでのファイル処理を行うプラグイン
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Troi Automatiseringから発売されているファイルメーカーPro用のプラグイン「Troi File Plug-in」がVer.2.7になった。以前のバージョンから約1年ぶりのバージョンアップとなる。ファイルメーカーProでファイルの読み書きあるいはコピーなどのファイル処理の機能を利用できるようになる。新しいバージョンでは、Mac OS X 10.3での動作を改良し、長いファイル名の場合の問題などを解消している。
    Troi File Plug-in 2.7
    http://www.troi.com/software/fileplugin.html

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃AppleScriptで使えるXSLT処理プロセッサ
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Late Night Softwareは、AppleScriptでXMLデータを扱うための機能拡張「XSLT Tools 2.0」のβ版を公開した。OSAX形式の機能拡張とサンプルプログラムなどからなっている。XML処理のコア部分は、ApacheプロジェクトのXerces 2.3.0やXalan 1.6を使用し、IBMのUnicode関連ライブラリのICU 2.6も使用している。スタイルシート変換などの機能が使え、以前のバージョンではできなかったノードの並べ替えなどにも対応している。XSLT Toolsは無償で利用できるソフトウエアだ。

    XSLT Tools 2.0b1
    http://www.latenightsw.com/freeware/XSLTTools/beta.html

    MOSAからのお知らせと編集後記は割愛します

    MOSA Developer News   略称[MOSADeN=モサ伝]
    Apple、Mac OSは米国アップルコンピュータ社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。
    このメールの再配信、および掲載された記事の無断転載を禁じます。
    http://www.mosa.gr.jp/
    Copyright (C)2004-2006 MOSA. All rights reserved.

  • MOSA Developer News[MOSADeN=モサ伝]第97号

    2004-01-20

    目次

    • Macworld San Francisco 2004レポート  佐藤 徹  【後編】
    • Cocoaでいこう! Macらしく 第35回   Yoshiki(DreamField)
    • 藤本裕之のプログラミング夜話 #37
    • 高橋真人の「プログラミング指南」 第36回
    • ニュース・解説
    • MOSAからのお知らせ

    Macworld San Francisco 2004レポート  佐藤 徹       【後編】

    4. iLife 4
     iPhoto/iTunes/iMovie/iDVDそしてGarageBandを加えて、iLifeは4.0というバージョンに統一され、今後は無料ダウンロードは停止され、新製品へのバンドルとiLifeパッケージ販売となるようです。
     各アプリケーションはかなり思い切った改良がされており、Macがデジタルハブとなってデジタル機器の中心に据えられ、データを密接にやり取りしながら交換するという役割をさらに推し進めています。
     iPhotoの改良に見られるように、Macのユーザが持つ大量のデジタルデータを整理するための提案もなされています。つまり、200~300の写真のうちはなんとなく整理できていましたが、デジタルカメラを使い始めて2~3年たったユーザーが撮りためた写真ファイルが20000~30000となると、閲覧・整理・編集するだけでも、新しい手法が必要になってしまうということをまず、注意喚起しています。iPhotoでは写真ファイルにメタデータを追加し、さまざまな切り口で整理する手法を実際のアプリケーションという形で提案しています。いわゆるデジタルアセットマネージメントに近い思想が入りつつあります。

     iPhotoのアプローチでは、ファイルを入れる先は同じで、カメラからの取り込みはできるだけ簡単に同じフォルダへ収納し、後で、日付やランク、アルバムを手がかりに整理し、最終的には印画紙に印刷してリアルなフォトアルバムにするという一連の手順を守っています。スライドショーには、Cubeトランジッションやスライドショー毎の細かい設定が出来るようになり、つまるところ、コンピュータ上でなければ出来ないフォトスタンドを実現しています。

     iTunesはよりApple Music Storeとの連携が強くなり、世界最大の音楽購入サービスとして、Apple Music Store自体の機能も日々更新されています。iTunes Essentialsやクラシック音楽・Billboard Chartとの連携(しかも1946年版から)によって、音楽のカタログとしても世界最高のものを目指しています。実際、音楽を購入できない日本でも、このカタログ機能を使うだけで、特定アーチストのディスコグラフィーなどを非常にみやすく参照できます。

     GarageBandは新しい領域である、音楽創りをサポートするアプリケーションです。その名の通り、足りない楽器パートメンバーをコンピュータで補って自分だけのバンドを作り、演奏を楽しむためのアプリです。ギターやピアノの演奏経験のある人は多いと思いますが、実際にドラムやベース・その他のメロディー楽器を組み合わせてバンドで演奏した人は少ないと思います。このアプリはかなりリアルなソフトウエアサウンドを使用して実際のバンド演奏に近い楽しみ方を出来るようになっています。50の楽器と1000のループ、200のエフェクトが用意されており、いずれも品質はプロ向けのものです。
     アマチュア演奏家が一人でも演奏を楽しめるように特化して作ってあるので欲張った複雑な機能が少なく、非常によくできています。アップル推奨の低価格で高性能のMidiキーボードもM-Audioから発売されており、自慢のギター・ベースサウンドを使用するとキーボードだけで弦楽器の微妙なニュアンスも再現できるようになっています。自作ループを作る場合では、リズムやビートのセンスがなくても、自動的にテンポに合わせたり、リアルタイムで楽器を換えたりできるので、安心してフィーリングだけで演奏を楽しみながら曲を作っていく事が出来るでしょう。出来た結果をAACファイルに書き出して、iTunesで聞けるというのも大きな魅力です。

    5. iPod mini
     iPodの新しいモデルであるiPod miniが発表されました。累計出荷台数200万台を越えたiPodはiTunesのWindows対応によりさらに出荷台数を伸ばしていて、MP3プレイヤーでの現在のシェアは31%です。しかし、低価格帯とハイエンドFlushメモリ方式がそれぞれ残りのシェアを分け合っており、iPod miniはハイエンドFlushメモリ機種のシェアに食い込むモデルとして紹介されました。
     ユーザーはもっとアクティブな生活(ジョギングやダンスしてる間など)の中で音楽を聴きたいと思っているので、より小型で価格の低いものを求めているようです。ただし、ハイエンドFlushメモリ機種も収納できる曲数を増やそうと思うとフラッシュメモリを増設しており、4Gのハードディスクを搭載するiPod miniは競争力があると強調しました。
     iPod miniは4GのHDに1000曲収納でき、現行モデルと機能もインターフェイスも変えないことを基本としています。ただし、容量の制限から(技術的な問題ではなく)録音機能と写真データの収納機能は取り除いているそうです。外部インターフェイスは同じなので、今ある3rdパーティー製品の大部分は接続できます。

     全体を眺めての私見は、アップルが今まで通り革新的な製品を出し続け、利益の出る会社としてしっかりと将来を見据えていくというのは、姿勢としても実績としても理解したのですが、やはりMacのシェアは下がっており、Macコミュニティー全体としては、かなり厳しい状況がもうしばらく続くという感じがしました。今年の出展社の少なさにその反応が現れています。アップルが赤字を出して、Macが無くなってしまうという最悪の事態は当分ないのはわかりますが、それは、iPodと拡張性が比較的低いノート型で稼ぎ出しているものであり、しかも、販売チャネルとしては直営店の売り上げが大きく貢献しています。
     iLifeの有料化や.Macサービスの拡充、Apple Music Storeの拡大はアップルがサービスやソフトウエア販売比率を大きくするのに貢献し、今後良い方向に向かっていくとは思いますが、やはり業界に占めるシェアをもう少し伸ばしてもらわないと、3rdパーティーがMac OS Xでしか動作しない革新的なアプリケーションを開発するための投資をするとは思えません。ただし、2004年と2005年は、マイクロソフトが新しいOSを出さない予定であるので、Mac OS Xのアドバンテージを伸ばし、積極的に他社との協力関係を強化していけば、チャンスはあると思われます。
     また、プラットフォームに依存しないWebベースアプリケーションの開発も、そろそろ限界に来ており、ネイティブアプリケーションによるよりきめの細かいユーザへの対応が求められています。現在あるWebサービスがより汎用的なインターフェイスで機能毎に接続できるようになるとすれば、Mac OS Xネイティブアプリケーションでのチャンスと、アドバンテージを強調できる可能性も残っています。
     今年はショーそのものに華やかさがなく、San Francisco入りしていた取材陣の間にも暗い雰囲気が漂っていましたが、会社としてのアップルは健全な状態です。この後、財務報告なども発表になり、実際の売り上げや利益・マーケットシェアなどがわかりますが、悲観的になる結果は出ないでしょう。むしろ、MOSAのメンバーで、Macだけでビジネスをしようと思っている人たちは今年が正念場になるのかもしれません。6月にはまたWWDC 2004がありますので、そこで発表される新しい技術に期待をしましょう。
     なお、1月22日にMOSA主催の新年パーティーでもこの記事と同じ内容を発表したいと思っています。またみなさんとお会いするのを楽しみにしてます。

    Cocoaでいこう! Macらしく  第35回 Yoshiki(DreamField)

    NSTimerを使ってみよう(後編)

     前回の続きです。まずは、説明を続ける前に、本来はどう組めば良かったのかを記述しておきます。
     まずは、windowControllerDidLoadNib:の最後に付け加えたコードですが、次の様に書くべきでした。

        [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector
    ( timerAdjustWindowSize:) userInfo:theWindow repeats:NO];

     retainするのをやめて、adjustWindowTimerにポインタを格納するのもやめています。これにより、インスタンス変数、adjustWindowTimerは必要無くなりましたので、MyDocument.hから削除してかまいません。何でかと言いますと、自分自身では後でadjustWindowTimerを使う必要が無いからです。このコードを実行すると、NSTimerクラスのインスタンスが生成され、イベントループに組み込まれ、そちらでretainします。従いまして、自分で所有していなくても消えませんし、後で使うわけでも無いので、所有する必要は無いというわけです。
     次に、timerAdjustWindowSize:の実装ですが、次の様になります。

    - (void)timerAdjustWindowSize:( NSTimer *)aTimer
    {
        NSWindow *theWindow;
    
        theWindow = [ aTimer userInfo];
        theWindowRect = NSIntersectionRect( [ theWindow frame], [ [ theWindow screen] 
    visibleFrame]);
        [ theWindow setFrame:theWindowRect display:YES];
    }

     theWindowをaTimerから取得するようになりました。このメソッドの実行が終われば、自動的にNSTimerクラスのインスタンスは無効化され、イベントループから取り除かれることになります。
     最初からこうやって書けば混乱は少なかったのですが、誤った書き方をしてしまい、申し訳無かったです。そこで、この際ですから、NSTimerについて、もう少し突っ込んだ説明をしようと思います。今回の例では、Timerクラスのインスタンスから投げられるメッセージは一度だけですが、これが繰り返し投げるような指定になっていたらどうなるでしょうか。つまり、次の様なコードです。

        
    hogeTimer = [ [NSTimer scheduledTimerWithTimeInterval:hogeSec target:hogeTarget 
    selector:@selector( timerHoge:) userInfo:hogeObject repeats:YES] retain];
    

     この場合は、後に次のようなコードで繰り返しを止める必要があります。

        [ hogeTimer invalidate];
        [ hogeTimer release];
        hogeTimer = nil;

     つまり、後でhogeTimerが必要になるというわけですね。hogeTimerにinvalidateメッセージを送ってhogeTimerを無効化し、必要無くなったのでreleaseしています。この後、hogeTimerにnilをセットしているのは、無くなってしまったインスタンスに誤ってメッセージを送信しないようにするためです。もちろん、そんなことしないようにプログラムを組めば良いだけなのですが、こうやっておけば、間違えて送信しようとしても問題が起こりません。一種のフェイルセーフです。
     ところで、入門書の中には、NSTimerのインスタンスを生成する時に、retainしているものとしていないものの二種類があることをご存知でしょうか。実は、これはどちらでも動作します。こう書くと、この連載を読んで来た方は、後で自分が使う必要があるのに何でretainしなくても良いのだろうと、不思議に思われると思います。その理由は、hogeTimerが生成されると同時にイベントループに組み込まれ、そちらでretainされ、無効化されるまでは決してreleaseされないからです。つまり、invalidateメッセージを送るまで、消えることはありません。従いまして、自分でretainしなくても、それまでは大丈夫ということになります。でも、NSTimerの実装がそうだからと言って、retainしなくても良いのでしょうか。私個人の考えでは、これはたまたまreleaseされないだけだと思います。そもそもretain、releaseとは、自分に関係無いものは無視できるようにするための仕組みです。相手の実装を知ったからretainしなくても良いというのは、この目的に反します。従いまして、この場合でもretainするべきであると、私は思います。ただし、retainしなくても消えないということは、NSTimerのドキュメントにも書いてあることですから、どうするかは皆様の判断にお任せします。
     さて、それでは最後に、前回積み残した説明をします。何で最初に次の様なコードを書いたかです。

    - (void)timerAdjustWindowSize:( NSTimer *)aTimer
    {
        NSWindow *theWindow;
        NSRect theWindowRect;
    
        theWindow = [ adjustWindowTimer userInfo];
        [ adjustWindowTimer invalidate];
        [ adjustWindowTimer release];
        adjustWindowTimer = nil;
    
        theWindowRect = NSIntersectionRect( [ theWindow frame], 
    [ [ theWindow screen] visibleFrame]);
        [ theWindow setFrame:theWindowRect display:YES];
    }
    


     invalidateを送信しなければならないと勘違いしていたとはいえ、aTimerでNSTimerクラスのインスタンスへのポインタは渡って来るのですから、これをadjustWindowTimerに格納しておいて使う必要は無いでしょう。実は、普段組んでいるプログラムでは、さらに別の所でadjustWindowTimerを使っているのです。

    - (void)windowWillClose:(NSNotification *)aNotification{
        [ adjustWindowTimer invalidate];
        [ adjustWindowTimer release];
        adjustWindowTimer = nil;
    }
    


     ウィンドウのdelegateをMyDocumentにしておいて、上記メソッドを実装しておきますと、ウィンドウが閉じる直前に、このメソッドが呼び出されます。何のためにこんなことをしているのかと言うと、timerAdjustWindowSize:メッセージが投げられる前にウィンドウが閉じてしまう可能性を考えてのことです。もし、そんなことが起こってウィンドウが閉じた後にtimerAdjustWindowSize:メソッドが呼び出されてしまったら。存在しないウィンドウに対してメッセージを投げることになり、このプログラムは吹っ飛んでしまいます。もっとも、今回の場合、そんなタイミングでウィンドウを閉じることが可能なのか疑問も感じますが。本連載では、ここまで説明すると本質が分かりにくくなってしまうと思い(本当は必要無い可能性もありますし)、こういった対処は省いています。ですが実際に自分でプログラムを組む時には、微妙なタイミングで起こり得る事象を熟考し、この様な対処も組み込んでいます。

    藤本裕之のプログラミング夜話 #37

     御慶。
     やれやれ、正月こそ人並みに休むことができたものの、相変わらずの貧乏暇なし、あっちこっちの半端仕事に追われ、それでは食えないから大物も引き受け、しかしそうそう大物がつづくわけではないので半端仕事もしくじるわけにいかず、つまりはいつも追いまくられるようなテイタラクである。そんな風なので申し訳ないが、今週はロクな話ができない。せいぜいXcode1.1の悪口がセキの山だ(笑)。

     こないだハマったのは旧Project BuilderのターゲットをXcode Nativeにするときの弊害だ。……オレのように、Pure Javaのライブラリ(zipで圧縮されて「.jar」という拡張子がついてるヤツ)をCocoaから呼ぶため、JavaBridgeを使っているヤツだけかもしれないんだが、とにかくそういうターゲットをネイティブ化するといろいろとヘンなことが起きるんだよね。
     まず第一にProject Builderの時にはターゲットのウィンドウにあった「Cocoa Java固有の設定」とか「Pure Java固有の設定」という設定ページがなくなってしまう。……ちと解説が必要か。
     例えばオレのアプリが「SomeThingWonderful.jar」というJavaのライブラリを使っていたとすると、Project Builderでこれを使う設定をするには、このファイルを「Resources」のグループに入れて、上述「Cocoa Java固有の設定」の画面を出して「Javaを必要とする」というチェックボックスをオンにし、その下の「ルートディレクトリ」と「パス」という欄にそれぞれ「Contents/Resources」、「SomeThingWonderful.jar」と指定すれば良かった。
     で、実際こういう設定がしてあったターゲットをXcodeで「ネイティブにアップグレード」したモノは、ちゃんとこのJavaを使った部分も動くんである。だが、このアップグレードしちゃったターゲットであらたに「AnotherSomethingWonderful.jar」も使いたいとなった時、どの画面で追加すればいいのだ? どこにもそれらしい設定画面はないし、項目名もないのだ。動いてはいるものの「SomeThingWonderful.jar」の設定自体がどこでなされているのかも見えないのだ。これ、どーなってるのだ?

     そういうわけで窮すればなんとかというか背に腹はカエルの父さんというか、オレのプロジェクトには今のところ旧Project Builderのターゲットも未練がましく残してあるんだが、新規にXcodeでJavaBridgeを使うアプリを書きたい場合はどうすればいいのやら(当然と言えば当然だがXcodeで新規に旧Project Builderのターゲットは作れない)……。ずいぶんドキュメントを読んだつもりなんだが、未だに不明である。これ、もうJavaBridgeは使うなというAppleからの「無言のメッセージ」ですかね(実は「JavaBridge」のドキュメントはAppleのサイトからいつの間にか消えてるみたいなんだよね)。
     まだある。上に書いたように「Javaを必要とする」設定のターゲットをネイティブにすると、デバッグ時に起動されるデバッガが勝手に「GDB」から「Java Debugger」に切り替えられてしまうのである。Xcodeの実行環境で使えるデバッガにはこの2つの他に「AppleScript Debugger」があるのだが、そんなこと、今までGDBしか使ったことのないワタシは知らなかった。
     とにかくアップグレードして起動したとたん、デバッガがワケのわかんないメッセージ(キャッチされない例外を検出したとかなんとか)を出して終了してしまうようになり、しかも単なる「Run」だとマトモに動くという現象に頭をひねくりまくりましたがな。しかもこの使用するデバッガの設定は「アクティブな実行可能ファイル●●を編集」というメニューを選ぶと出てくる画面の中でしか変更できず、GDBしか使わなかった(したがってそれを変更する必要に迫られたことのなかった)オレはあの画面の下の方にそんなスイッチがあることすら知らなかったよ(ようやくXcodeのこれを見つけてからJaguarを起動してProject Builderで確認したらあれにもあった)。
     確かにJavaBridgeを使っているヒトは少数派らしく、Googleで検索しても500も見つからない上、見つかってももう開けないサイトがかなりあるという状態だ。Pure Javaでライブラリを書くことで、MacでもWindowsでもLinuxでも同じサービスを使うことができるというのは結構なメリットだと思うんだがなぁ。
    (2004_01_15)

    高橋真人の「プログラミング指南」第36回

    オブジェクト指向のとっかかり(22)

     こんにちは、高橋真人です。
     Mac OS Xに、最初から開発ツールが付属していることから、めっきりと存在の薄くなってしまったように見えるCodeWarriorですが、どっこいまだまだ根強い人気があるようです。
     何を隠そうこの私も、CW9を登場と同時に入手しまして、ウワサのPowerPlant Xをボチボチいじり始めています。
     前回お話ししたSTLですが、PowerPlant Xの中でも利用されています。「PowerPlantはC++のフレームワークなのだから当然」と考える方もおいでかもしれませんが、従来のPowerPlantにはSTLは取り入れられてはいませんでした。たとえば前回も取り上げたvectorに該当する役割をするクラスは、オリジナルPowerPlantではLArrayというクラスでした。
     このLArrayというクラス、配列の要素としてオブジェクトを持つ場合にはオブジェクトそのものではなく、そのポインタを格納しなければならないという仕様になっています。そのために私は最初、なかなか慣れずに苦労しました。
     よく使われるテーブル形式のUIを担っているLTableとその派生クラスなどにおいてもデータの格納にはこのLArrayの派生クラスを用いています。私はPowerPlantを使い始めたころ、この「オブジェクトを直接は格納できない」ということが分からなくて、散々試行錯誤を繰り返した末に結局フレームワークがわざわざ用意してくれた枠組みを使わずに、自分でデータ格納用のメンバーを追加してそちらを使うなどというバカなこともしたものです。
     オリジナルのPowerPlantにSTLが取り入れられなかった理由は時代的な背景などいろいろあるでしょうが、今回、新しいフレームワークとしてスタートしたPowerPlant Xで、独自のコレクションクラス群を追加することなしに、今やC++の標準のライブラリとなったSTLを使っていることは、当然なことであり、懸命なことだと思います。
     STLについては前回もほんの一部に触れただけで、別の機会に何らかの形で触れることはあるかもしれませんが、全体についての説明はとてもここでできるようなものではありません。私の説明能力の範囲も超えてしまいますし(笑)。

     さて、ずいぶんと間があいてしまいましたが、第33回目で掲載しましたプログラムソースの解説にいよいよ取りかかっていきます。
     main関数を頭から見ていきましょう。
     最初に、homeDirという名のローカル変数を定義しています。この変数はC++標準の文字列型であるstringというクラス(と今は考えておいてください)のインスタンスです。Cしかご存じない方には、定義の形がまるで関数のように見えると思いますが、これはstringのコンストラクタに対して引数を与えるための記法です。
     stringのコンストラクタは多重定義されていますので、複数用意されている中から、与える引数によって1つが選択されます。ここではconst char *、つまりC文字列が引数となります。ここで選ばれたコンストラクタは、与えられた文字列を格納するのに十分なメモリーを確保した上で文字列の内容(ただし、末尾のnull characterは含まない)を保持します。
     「引数にC文字列」と言っていますが、この文字列はgetenv()という関数から返された値です。この関数はUNIXの関数で、Macしか経験のない方には余りなじみのないものですが、他の環境ではおなじみの「環境変数」というやつを参照しています。
     引数に”HOME”という文字列を与えることで、カレントのホームの位置をPOSIXの形式で返してきます。例えば現在のユーザーがmosaの場合、/Users/mosaという文字列が返ってくるわけです。
     次に、同じくstringクラスの変数、targetFileを定義しています。今度はコンストラクタに与えられている引数は、C文字列ではなくてstringです。
     引数を見てみると、2つの要素が+演算子でつながれていることが分かります。演算子の左側はstring、右側はC文字列です。こういう場合C++では、グローバルの関数であるoperator+(string, const char *)か、stringクラスのメンバ関数であるoperator+(const char *)というのが呼び出されます。
     何だか、訳が分からないですね(笑)。C++では演算子の多重定義ができるようになっていますので、あらかじめ定義さえしておけば+演算子を使って数値でないものの「加算処理」ができてしまうのです。定義の仕方は、慣れないとかなり奇異に見える書き方ですが、operatorという識別子の後に多重定義したい演算子を続けた名前の関数として記述します。引数として演算子の左項、右項の順に与えます(2項演算子の場合)。
     で、stringとC文字列を加算する演算子は演算結果としてstringを返しますので、targetFileを構築するコンストラクタにはstringクラスの値が引数として与えられることになります。
     さて、今回の例ではhomeDirという変数を再利用するため、変数を2つ定義していますが、

    string targetFile(getenv("HOME"));
    targetFile += "/Desktop/text.txt";

    というように、targetFileだけを定義する方法もあります。
     ただし、以下のようにはできないので注意が必要です。

    string targetFile(getenv("HOME") + "/Desktop/text.txt");

     どうしてかと言いますと、演算子の多重定義というのはあくまでクラス絡みのものに限るのです。そのため、最低でも左右のどちらかの項はクラスでなければならないので、C文字列同士の「加算演算子」は定義できません。

     やれやれ。たった2行を説明するだけでこんなにかかってしまいました(笑)。やはりC++ってのはやっかいですね。
     もっとも、この2行は見かけ上は2行に見えても、内部ではもっと複雑な処理が実行されているということは、今までこの連載を読んでこられた方ならお分かりの通りです。

    ニュース・解説

     今週の解説担当:小池邦人

    Carbon ドキュメント & サンプル & SDK ナビゲーション(2004/01/16)

    【開発環境】

    IBM社からMac OS X用のC/C++とFortranコンパイラが発売になりました。昨年の8月頃からβ版として配布されていたのですが、ついに正式版が登場したようです。

    「XL C/C++ Advanced Edition V6.0 for Mac OS X」

    http://www-306.ibm.com/common/ssi/fcgi-bin/ssialias?subtype=ca&infotype=an&appname=iSource&supplier=897&letternum=ENUS204-005

    「XL Fortran Advanced Edition V8.1 for Mac OS」

    http://www-306.ibm.com/common/ssi/OIAccess?DocURL=http://d03xhttpcl001g.boulder.ibm.com/common/ssi/rep_ca/4/897/ENUS204-004

    IBMが開発していますので、当然のことながらPowerPC 970に完全に最適化されており、非常に優秀なコンパイラだという噂です(どなたか使ってみましたか?)。XL C/C++についてのウェブ上の解説を読んでみると、嬉しいことにちゃんとXcodeに対応していると明記されています。ただし、価格や日本からの購入方法がよくわかりません。利用された方は、ぜひMOSADeNに詳しいレポートの提出をお願い致します(笑)。

    Apple社のDeveloperサイト内にデベロッパ向けの新しいサイトが3つオープンしました。「Xgrid」については、前号の新居さんの解説や筆者の使用体験談を参考にしてください。

    「Science Education Site」

    http://www.apple.com/education/science/

    「Enterprise IT Site」

    http://developer.apple.com/enterpriseit/

    「Apple Xgrid Site」

    http://developer.apple.com/hardware/ve/acgresearch.html

    【テクニカルドキュメント】

    前回から1月16日の期間中、Apple社のDeveloperサイトに8つのドキュメントが新規登録されました。若干の改訂版も含まれています。「Introduction to Displaying Data in a Data Browser」や「Data Browser Reference」は、Carbon Frameworkのデータブラウザ用APIの解説ドキュメントなのですが、今まではテクニカルノートしか存在していませんでした。正式ドキュメントが出るまで何年かかったことやら…(涙)。

    「What’s New in QuickTime 6.5」(PDFあり)

    http://developer.apple.com/documentation/QuickTime/WhatsNewQT6_5/index.html

    「Data Browser Reference」(PDFあり)

    http://developer.apple.com/documentation/Carbon/Reference/databrow_reference/index.html

    「Introduction to Displaying Data in a Data Browser」(PDFあり)

    http://developer.apple.com/documentation/Carbon/Conceptual/display_databrowser/index.html

    「Introduction to Mac OS X Frameworks」

    http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/index.html

    「Introduction to the Mac OS X File System」

    http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html

    「Apple Event Manager Reference」(PDFあり)

    http://developer.apple.com/documentation/Carbon/Reference/Apple_Event_Manager/index.html#//apple_ref/doc/uid/TP30000134

    「Optimizing Your Code Footprint」

    http://developer.apple.com/documentation/Performance/Conceptual/CodeFootprint/index.html#//apple_ref/doc/uid/10000149i

    「Introduction to Cocoa Bindings」

    http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaBindings/index.html#//apple_ref/doc/uid/10000167i

    また、デベロッパ向けの読み物として以下の内容が追加登録されています。

    「Marratech Gains Customers with Port to Mac OS X」

    http://developer.apple.com/business/macmarket/marratech.html

    「Creating Secure Transactions on Mac OS X Server Using SSL」

    http://developer.apple.com/server/security_ssl.html

    1月16日までに新規テクニカルノートはひとつも登録されませんでしたが、テクニカルQ&Aの方は1つだけ登録されました。日本語訳もありますが、英語バージョンの方が再登録となりますので注意してください。

    QA1249 How can I find out what non-RGB pixel formats a codec supports?

    http://developer.apple.com/qa/

    【サンプルソースコード】

    前回から1月16日の期間中、Apple社のSample Codeサイトには1つのサンプルソースコードが登録されました。QuickTimeを利用してDVデータをビデオ出力させるサンプルアプリケーションで、こちらも再登録となります。

    「SimpleVideoOut」(QuickTime関連)

    http://developer.apple.com/samplecode/

    【デベロップメント SDK】

    前回から1月16日の期間中、Apple社のDeveloperサイトに登録された新しいデベロップメントSDKはひとつもありませんでした。

    http://developer.apple.com/sdk/

    MOSAからのお知らせと編集後記は割愛します

    MOSA Developer News   略称[MOSADeN=モサ伝]
    Apple、Mac OSは米国アップルコンピュータ社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。
    このメールの再配信、および掲載された記事の無断転載を禁じます。
    http://www.mosa.gr.jp/
    Copyright (C)2004-2006 MOSA. All rights reserved.

  • MOSA Developer News[MOSADeN=モサ伝]第96号

    2004-01-13

    目次

    • Macworld San Francisco 2004レポート  佐藤 徹  【前編】
    • Cocoaでいこう! Macらしく  第34回  Yoshiki(DreamField)
    • Xgridテクニカルプレビュー版を試す   小池 邦人
    • 「Behind the WebObjects」  第11回  田畑 英和
    • ニュース・解説
    • MOSAからのお知らせ

    Macworld San Francisco 2004レポート  佐藤 徹       【前編】

    Macworld San Francisco 2004レポート

      有限会社 ガラパゴスシステムズ
      MOSA 常任理事  佐藤 徹

     今回のMacworld San Francisco 2004に参加しましたのでレポートします。今年は全体としては目立った新製品発表があまりなく、また、展示会場は例年通り2会場(Moscone Center NorthとSouth)が使用されていましたが、出展者数が昨年の半分という状態で、展示会場の方はかなり盛り上がりに欠けるものとなっていました。詳細なレポートは他の媒体のニュースや紙面にまかせるとして、今回のレポートはSteve Jobsによるキーノートを中心におおまかな様子を紹介します。

    キーノートスピーチより

    1. Appleのこれまでの歩みと2004年の持つ意味
     今年は1984年のMacintosh誕生からちょうど20年目の、20th Anniversary of Macintoshの年です。Macintoshがデスクトップコンピュータの歴史を変えるイノベーションを行ったわけですが、アップルは現在もイノベーションを続けており、自分自身に対して再イノベーションを行うという事を行い続けていることを強調しました。
     1984年に「1984」というスーパーボールの試合中に一回だけ放映したMacのプロモーションフィルムがありますが、今回はスペシャルエフェクトを加えてリメイクしたものを会場に流しました。支配者にハンマーを振るって抵抗する女性がiPodを装着しているというものでした。アップルは20年後にコンピュータではシェアが大きく下がってしまっいましたが、MP3プレイヤーという全く新しい分野でシュアを伸ばしており、Windowsのユーザーにも提供されているというメッセージをうけとりました。
     Steve Jobsは2004年にどんな革新的なことを行うかもちろん明言はしませんでしたが、特別な年であることは強調し、今年もまた革新的な製品を出荷し続ける事は約束しました。

    2. Mac OS X
     現在までに930万人のユーザーが実際にMac OS Xを使っており、次の4半期には1000万人になるだろうという結果が発表され、現在1000のネイティブアプリの存在と、アップルを含めたアプリケーションメーカーのコミットを得られている事を強調しました。この結果を受けて、OSの移行作業は完了したと宣言されました。つまり、ユーザのMac OS Xへの移行は終了しており、今年はMac OS Xで動くマシンとアプリケーションだけにフォーカスするという事です。
     2004年の前半に出荷される予定であるマイクロソフト Office 2004のアルファ版のお披露目がされました。WordへのノートブックインターフェイスやEntourageのプロジェクトセンター機能など、緻密なユーザーフィドバックの分析の結果追加された新機能を披露しました。今回のMac BU(Macintosh Business Unit)の責任者は実際にMacの誕生から関わっている人で、マイクロソフトMac BUは1984年のMacの誕生以来最初の3rdパーティーアプリケーションを含めてMac向けにアプリケーション開発を行った実績が強調され、今後も開発を続けていくことがマイクロソフトの責任者からアナウンスされました。今年は、ブーイングもなく、アナウンスもデモも淡々と行われ、Office 2004では、新しい機能が最初にMac OS X向けに出荷される事が強調されました。

    3. Xserve G5と企業向け・高等教育市場
     G5に関しては、発表と同時に進行し、昨年のWWDCで話題になったバージニア工科大学での成功例がまず紹介されました。1100台のマシン(2200 CPU)を使用し、特別に設計された高速インターフェイスカードでそれぞれのマシンがノードとして密に接続され、10 TF(テラフロップ)という世界第3位の結果を出しました。性能は1位のEarth Simulatorの1/3だが費用は1/100という結果です。
     ハードウエアの新製品としてXserve G5が紹介されました。おおかたの予想に反して、1Uサイズでの出荷です。2GHzのシングル・デュアルのG5を搭載し、現行のG5と同じマザーボードを用いて実現しています。さすがにCPUの冷却設計は大幅に手直しされ、全面に吸気用の取り入れ口が2つあり、内部の冷却ファンも大型ファン2個から小型ファンの組み合わせに変更されています。
     内部の変更としては、ECC付 DDR400のメモリを採用し、メモリスロットは8つ用意しています。ディスクスロットは3つに減ったものの、総容量は現行と変わらないように、Serial ATA 250Gドライブモジュール(値段はATA/100と同じ)を採用しており、オプションのハードウエアRAIDサポートによって高スループット・高信頼性のストレージをXserveだけでも構築可能となりました。
     オンボードにGigabit Ethernetを2基搭載となったため、上下2つあるスロットはFibre ChannelやハードウエアRAIDカードに使用する事ができます。また、最大入力電流が低く抑えられており、定格消費電力は345Wとなっています。
     Xserve RAIDもマイナーチェンジされ、基本的には現行モデルと大きな違いはないのですが、ATA/100 250Gのディスクモジュールの採用によって容量が最大3.5Tバイトに増えました。
     RAID Adminのアップデートによって Raid Set Slicing機能が使えるようになり、ディスクモジュールより小さなRAIDセットを作って、より多くのサーバに分割・供給できるようになりました。また、Raid Set Expansion機能は、ディスクドライブを追加する際にダウンタイム無しに拡張できる機能です。
     Xserve RAIDがWindows 2003サーバやRed Hat Enterprise Linuxでの認定を受けることにより、Mac OS X以外のプラットフォームでも動作するように環境が整いました。また、現行ではVixelだけであったFibre Channel SwitchもBrocadeなど、複数のメーカーの正式認定製品が追加され、さらにVERITAS Volume Managerストレージ管理などが認定プログラムに使用されているため、マルチベンダー環境でのストレージネットワークへの接続・運用も各社から正式にサポートされます。
     これ以外のサーバ製品群もアップルと製品提供メーカとの間で、アライアンスプログラムが提供されつつあり、将来はOracle・Sybaseなどのデータベース製品でもより強力なサポート体制が確立するはずです。

     なお、1月22日にMOSA主催の新年パーティーでもこの記事と同じ内容を発表したいと思っています。またみなさんとお会いするのを楽しみにしてます。
    【後編へつづく】

    Cocoaでいこう! Macらしく  第34回 Yoshiki(DreamField)

    NSTimerを使ってみよう

     前回、NSTimerクラスを使用しましたが、これの説明はしていませんでした。そこで今回、その説明をするために最新のリファレンスを読んだのですが、「え?こんなこと書いてあったっけ?」。ご免なさい。前回紹介したプログラムは余計なことをしてしまっています。そう言えばNSTimerについて調べたのは、まだJaguarさえ出ていない頃。確かこんなに詳しくは書いてありませんでした。もちろん、この連載を書く時には、念のためになるべく最新のリファレンスを確認しているのですが、前回、NSTimerの説明を次回に廻してしまったため、確認を怠たっていました。申し訳ない。ただし、このままでも動作はします。
     さて、どこがまずいのかは説明の中で触れます。まずはwindowControllerDidLoadNib:の最後に付け加えたコードを見て下さい。

    adjustWindowTimer = [ [NSTimer scheduledTimerWithTimeInterval:0 target:self 
    selector:@selector( timerAdjustWindowSize:) userInfo:theWindow repeats:NO] retain];
    

     NSTimerクラスは、一定時間後に、指定したメッセージを指定したオブジェクトに送ることが出来るクラスです。ここでは、NSTimerクラスのインスタンスを生成しています。上記コードだけではパラメタの説明がしにくいので、リファレンスを合わせて見て下さい(NSTimerクラスが書いてあるのは、Foundation Reference for Objective-Cの方です)。リファレンスには次の様に書いてあります。

    + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target 
    selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats
    

     secondsは、何秒後にメッセージを送信するのかを指定します。ここには0を指定していますから、0秒後です。targetは、どのオブジェクトにメッセージを送信するのかを指定します。selfを指定していますから、自分自身です。aSelectorは送信するメッセージを指定します。送信するメッセージはtimerAdjustWindowSize:なのですが、これを文字列としてそのまま指定することは出来ません。何故ならメッセージはコンパイル時に、SEL型の内部表現の値に変換されるからです。ここで使われている@selector()は、プログラム上の文字列表記から、SEL型のデータを得るコンパイル指示子です。userInfoは、何か付加情報を渡したい時に指定します。必要無い時にはnilでかまいません。ここではウィンドウを指すポインタを指定しています。最後のrepeatsは、このメッセージを繰り返し送信するか否かを指定します。ここではNOを指定していますから、送信するのは一度だけです。
     まとめますと、ここの実装では、0秒後に一度だけ自分自身にtimerAdjustWindowSize:メッセージを送信するという指定になります。ここで勘違いしないで欲しいのは、NSTimerはマルチスレッドは使っていないということです。NSTimerオブジェクトはイベントループに組み込まれ、そこから指定した時間後にメッセージを送信してもらうことにより、見かけ上の並行処理を実現しています。この辺りの方式は、Macでプログラムを組んでいた方にとってはおなじみですね。このため、イベントループに戻らなければ決して実行されませんし、確実に指定した時間に実行されるとも限りません。こう書くと、マルチスレッドを使った方が良いのではないかと思われるかもしれませんが、そもそもマルチスレッドというのは、本当に並行に処理をする必要が無い時には、かえってプログラムの複雑さが増し、性能も落ちるのです。ですから、本当に必要なのかどうかを良く考え、その必要が無ければやみくもに使うべきではありません。今回の場合は、ウィンドウが表示されてから実行したいだけなのですから、むしろマルチスレッドを使わない方が都合が良いと言えます。
     次に、メッセージを送信された結果、実行されるメソッドの実装を見てみましょう。

    - (void)timerAdjustWindowSize:( NSTimer *)aTimer
    {
        NSWindow *theWindow;
        NSRect theWindowRect;
    
        theWindow = [ adjustWindowTimer userInfo];
        [ adjustWindowTimer invalidate];
        [ adjustWindowTimer release];
        adjustWindowTimer = nil;
    
        theWindowRect = NSIntersectionRect( [ theWindow frame], [ [ theWindow screen]
     visibleFrame]);
        [ theWindow setFrame:theWindowRect display:YES];
    }
    


     送信するメッセージの形は決まっています。戻り値無しのvoid型で、引数としてNSTimerオブジェクト自身が渡って来ます。このNSTimerオブジェクトにuserInfoメッセージを投げますと、NSTimerオブジェクト生成時に指定したuserInfoを返してもらえます。こうやって付加情報のやり取りをします。ここではウィンドウを指すポインタを受け取っていますね。さて、ここで引数で渡って来るのなら、adjustWindowTimerなんてインスタンス変数は必要なかったのではないかという疑問が湧くと思います。ここで書いた範囲のコードでは、その通りですね。ここも見落としていました。これの説明は後で行います。
     最初に書いた、明らかに余計なことをやっているのは、この次の行です。

    [ adjustWindowTimer invalidate];

     invalidateメッセージを投げると、投げた先のNSTimerオブジェクトが無効になり、遠からずイベントループから取り除かれます。ところが、リファレンスによると、repeatsにNOを指定した時には、メッセージを投げた後に自動的にこれが行われると書いてありました。従いまして、今回、これは必要ありませんでした。
     さて、何でNSTimerオブジェクトをretainしているか等、まだまだ説明が残っていますが、それは次回に続きます。

    Xgridテクニカルプレビュー版を試す   小池 邦人

    2004年サンフランシスコエキスポの基調講演において、Apple社よりXserve G5が発表されました。それと同時に、以前から噂に上がっていたPCクラスタリング技術「Xgrid」のテクニカルプレビュー版(ドキュメントにはαリリースとの記載あり)が登場したので、さっそく試してみることにしました。実行環境やサンプル、ドキュメントを含んだ「Xgrid 1.0 Technology Preview 」は、以下のサイトからダウンロードすることが可能です。

    http://developer.apple.com/hardware/ve/acgresearch.html

    PCクラスタリングは、サーバ障害時のリカバーや負荷の分散時などにも活用されていますが、Xgridのターゲットは膨大な数値計算を複数のMacintoshで分散処理する用途です。最近では、1100台のPowerMac G5で構成したバージニア工科大のPCクラスタが、速度ランキングの世界第3位となり関係者を驚かせました。基本的には、それと同じ用途と言うわけです。ちなみに、この大学においてもXgridの動作テストを行っているそうです。まあ、一般のパソコンユーザにはあまり馴染みのない世界となりますが、3Dソフトによる分散レンダリングやXcodeによる分散コンパイルなど、一般ユーザにまったく無縁の世界かと言うと、そういうわけでもありません。

    「Xgrid 1.0 Technology Preview 」を伸張し、それに含まれるXgrid.pkgをインストールすると、/Library/Xgrid/に実行環境やフレームワーク、プラグイン、ドキュメントなどがインストールされます。各種ドキュメントの内容はパッケージと一緒に添付されている物と同じです。アプリケーションフォルダにはXgridアプリケーション本体が保存され、「システム開発環境」に表示されたXgridによりクラスタリングに関係する各種設定が行えるようになります。このプレビュー版では、1台のMacintoshでもXgridの動作確認が可能となっています。まずは単独マシンでXgridを起動し、その仕組みを確認してみます。

    Xgirdアプリケーションを起動するとウィンドウが表示され、Xgridのサービスが利用できるかどうかサーチが開始されます。しばらくすると「サービスが見つからない」と言う主旨のアラートが表示されます。アラートを閉じたら「Start Local Service」を押してください。すると、「New Job」というウィンドウがオープンしますので、左側のブラウザに表示されている「localhost」をダブルクリックします。「Cluster Nodes」という別ウィンドウが開き、1台のみのMacintosh(localhost)が利用可能であることが分かります。Jobウィンドウの右側のブラウザから「Mandelbrot」をダブルクリックすると、マンデンブロー集合を計算し結果を描画する処理が実行されます。その隣には、処理全体のクロック数を示すメータウィンドウが表示されています。

    先程の「Cluster Nodes」ウィンドウの方を見ると、演算が実行されている間はStatusが「Working」に変わり、PowerBookアイコンの画面に実行中のサインが表示されます(Newtonのアイコン?)。こうした処理を複数台で分散させて行うのがXgridの役目ですから、今度はローカルネットワークで接続された2台のMacintoshで同様の処理を行ってみます。以下の実行方法の詳しい内容を知りたい場合には、パッケージに付属している「ReadmeFirst.pdf」を参照してください。Xgridでは、各マシンに処理を振り分け、その結果を集計する仕事を請け負うマシンをコントローラ、分散処理を担当するマシンをエージェントと呼ぶようです。

    最初に「システム環境設定の」Xgridでコントローラ(今回はエージェントも兼ねる)の設定を行います。「Agent Security」「Controller」「Controller Security」の各タブでパスワードを設定してください。すべて同じ内容でかまいません。続いて、「Agent」タブの「Choose when the agent may accept task:」を「Always」に切り替えます。これでつでも分散処理が実行されます。そうでない場合、エージェントマシンはスクリーンセーバが起動している間のみ処理が実行されます。「Agent」と「Controller」の「Start」ボタンを押せばサービスが開始され設定作業は終了です。続いてエージェント側のマシンも同様な設定を行い「Agent」の「Start」ボタンだけを押します。これですべて終了です。

    コントロール側のマシンでXgirdアプリケーションを起動します。設定が正しければアラートは表示されず、「Service:」にコントロール側のマシン名が表示されます。設定したパスワードを入力し「Connect」ボタンをクリックすると「New Job」ウィンドウがオープンします。1台で試した時に「localhost」と表示されていた場所に「Rendezvous」と表示されていますので、それをダブルクリックします。「Cluster Nodes」ウィンドウに2台のマシンが表示されており、どちらもStatusが「Available」であれば成功です。先程の「Mandelbrot」を実行しましょう。両方のマシンで演算処理が分散されていることが理解できると思います。Xgridでは、ネットワーク上の利用可能なエージェントマシンを探す時にRendezvousネットワーキング技術を利用します。よって面倒なネットワーク設定をすることなく、すぐに分散作業を開始することが可能となります。

    Xgridは、NeXT時代の「Zilla」というプロジェクトが元になっているそうです。このプロジェクトは2001年にApple社のAdvanced Computation Groupに引き継がれ「Xilla」と名を変え、現在のXgridに至っているそうです。現状では科学計算などの分野がターゲットとなるでしょうが、Macの世界でこうした面白い技術が一般ユーザに開放されると、思わぬ利用形態が発生するケースがあります(笑)。将来的にはどんな方向へ進化するのか分かりませんが、とても楽しみな技術です。正式版が発表され、もう少し詳しい技術ドキュメントが入手可能になったら、分散処理環境で動作する自作アプリケーションを作成してみたいと考えています。

    「Behind the WebObjects」  第11回  田畑 英和

     今回もD2Wの解説で、前回の続きでルールの説明をおこなっていきましょう。D2Wではルールによってアプリケーションの動作を制御することができますが、まずD2Wのプロジェクトが生成された直後のルールファイルをみておきましょう。プロジェクトが生成された時にResourcesグループの中には自動的にルールファイル”user.d2wmodel”が作成されています。
     ルールファイルを編集するツールとしてRuleEditorがWebObjectsの開発環境に含まれていますが、このRuleEditorで”user.d2wmodel”を開くとルールの確認や編集ができます。Project BuilderやXcodeからRuleEditorでルールファイルをうまく開けれないときは、ルールファイルを選択しコンテキストメニューから「Finderで開く」を実行してください。

     RuleEditorですが、1ウインドウのシンプルなツールです。画面の上半分に定義済みのルールがリストアップされ、特定のリストを選択すると画面の下半分にルールの詳細が表示され、そのルールの編集が可能になります。
     Fileメニューの「Filter Rules…」からはルールの検索が実行でき、特定の条件にマッチするルールのみを絞り込んで表示することができるので、ルールの数が増えた時に便利です。
     初期状態の”user.d2wmodel”をRuleEditorで開くと、以下のようなルールが1つだけ定義されていることが確認できます

    Lhs : *true*
    Rhs Key : look
    Rhs Value : BasicLook
    Priority : 100

     これはプロジェクト作成時にアシスタント上で指定したLookの設定がルールに反映されたものです。ここでルールの形式を説明しておきましょう。ルールは大きく分けて”Left-Hand Side(Lhs)”と”Right-Hand Side(Rhs)”に分かれ、Lhsではそのルールをどんなときに適用するかの条件を定義しています。Lookのルールの場合はアプリケーション全体で適用するためLhsの指定は省略されています。RhsではKeyとValueのペアによりルールの内容が定義され、Lookの設定を見ていますと、”look”というkeyに対して”BasicLook”というValueが指定されていることが分かります。最後のPriorityですが、これはルールの優先順位になります。
     このような形式のルールがアプリケーションの実行時に解釈され、特定のタイミングで特定のルールが実行されるようになっています。ルールの形式をみてみますとLhs -> “Rhs Key” = “Rhs Value”のような構造になっていますが、これは「〜の時に、xxxはyyy」といったような意味であることが分かります。今回の場合は「常にlookはBasicLook」といった意味をもつルールになっているわけです。

     では次にLookのルールを書き換えてみたいとおもいます。アシスタント上では3つのLookが選択できましたが、それぞれのLookに対応するValueは次のようになっています。

    Basic Look -> “BasicLook”
    Neutral Look -> “NeutralLook”
    WebObjects Look -> “WebObjectsLook”

     ”user.d2wmodel”に定義されていたRhs Valueを別のLookのものに書き換えると、アプリケーションのLookが変更されることが確認できます。このときルールを変更するためにアプリケーションを停止させたり、プロジェクトを再ビルドする必要はありません。WebObjects Builderでの変更が直接アプリケーションに反映されたのと同様に、ルールの変更は起動中のアプリケーションに直接反映されます。
     ルールを書き換えるだけでアプリケーションのLookを変更されることができましたが、プロジェクトの生成時に特定のLookを設定した場合と、プロジェクトを生成した後に特定Lookを指定した場合では少しだけ違いがあります。それはMain画面とそれ以外の画面のレイアウトおよびメニューヘッダーです。第9回の連載で説明しましたようにこれらのコンポーネントは直接プロジェクト内に作成されるためルールを書き換えただけでは変更することができません。一方Main画面とメニューヘッダー以外はD2Wのフレームワークによって提供されていますので、ルールの書き換えだけで変更できるようになっています。つまりD2Wの世界はルールによって制御がおこなわれているというわけです。

     ”user.d2wmodel”ではLookに関するルールしか定義されていませんでしたがその他の様々な処理もルールによって制御されています。ではそのルールがどこに存在するかですが、D2Wのフレームワーク内にはすでに定義済みのルールが存在しています。つまりD2Wのフレームワークはルールによって呼び出される様々な機能が実装されているだけではなく、あらかじめルールまでもが定義されており、アプリケーションの様々な場面でどのような処理をおこなえばよいかということがあらかじめ設定されているのです。このことにより、D2Wではプロジェクトを生成しただけですぐに実行できるアプリケーションが作成できるのです。それでは次回もさらにD2Wの世界を詳しくみていきたいと思います。

    ニュース・解説

     今週の解説担当:新居雅行

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃Mac OS Xのデバイスドライバ周りの情報サイト
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Mac OS Xのデバイスドライバ関連の情報提供を行うサイト「Mac OS X Device Driver」が、inADA社の稲田元彦氏によって開設されている。Info.plist関連情報、マウスドライバを作成する方法、アプリケーションからカーネルを利用する方法など、いくつかの情報がPDFとして公開されている。また、メーリングリストも開設されており、情報交換の場もある。いずれも、閲覧・参加は無料でできる。また、稲田氏によるIEEE1394かkextドライバ関連のWebLogも用意されている。Mac OS Xのドライバ開発が必要になった場合、基本的な情報を得ることに加え、人脈をたどることもできるコミュニティになりそうだ。

    inADA
    http://homepage.mac.com/inada/

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃グリッドコンピューティングを簡単に実現するXgrid
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    2004年初頭のMacworld Expoは例年とおり華々しいキーノートスピーチが開催されたが、そこで紹介されなかった新しいソフトウエアとして「Xgrid」がある。これは、Mac OS X 10.2.8以降のシステムで利用可能なグリッドコンピューティングのための基本システムである。何台かのMacにこのXgridをインストールすることで、複数のコンピュータで処理を分散させるグリッドコンピューティングが実現する。Mac同士はRendezvousで認識をすることから非常に簡単にグリッド処理をさせることができるが、ソフトウエアもインストーラ形式になっているため、いずれにしても簡単に導入できて利用できるグリッドという特徴を持っている。
    すでにグリッド利用の実績のあるBLASTはXgridに対応しているが、通常のアプリケーションがXgridを使ってグリッドコンピューティングを行うには、もちろんXgridに対応させる必要がある。Xgridはタスクをあちらこちらのコンピュータに分散させて行うという仕組みを提供する。あちこちのコンピュータに命令を送って結果を集めるといった作業をXgridが行うわけだ。この機能を利用するために、アプリケーションはXgrid対応のプラグインを作成する必要がある。プラグインの作成方法もXgridのディスクイメージの中にあるので、開発者は要チェックだろう。
    なお、Xgridは、Xserveのクラスタノードモデルでの利用だけでなく、Mac OS X 10.2. 8以降なら本体は問わないようである。オフィスや研究室内のMacを使っていない時間帯で活用するという利用法も考えられる。また、繰り返しの多い科学技術計算といった分野にグリッドを応用するという事例はよく聞かれるが、画像処理やビデオのエンコードと言った時間のかかる処理は、実務の世界でも出くわすことは多い。各種のアプリケーションで対応してみる価値のある機能かもしれない。

    Apple Xgrid 1.0 Technology Preview
    http://developer.apple.com/hardware/ve/acgresearch.html

    ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    ┃Mac OS Xのシステムに関する文書が公開
    ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
    Mac OS Xに関するいくつかの文書が公開されている。ファイルシステム、フレームワーク、バンドル、実行ファイルに関するもので、基本的な情報はMac OS Xリリース時に公開されているInside Mac OS X:System Overviewでも掲載されているものだ。しかしながら、その後のアップデートにともなっていろいろと変化している内容についてもフォローされており、また、情報が整理されていることもあるので、心にとどめておきたい文書群である。

    The Mac OS X File System
    http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html

    Mac OS X Frameworks
    http://developer.apple.com/documentation/MacOSX/Conceptual/BPFrameworks/index.html

    Mac OS X Bundles
    http://developer.apple.com/documentation/MacOSX/Conceptual/BPBundles/index.html

    Runtime Configuration
    http://developer.apple.com/documentation/MacOSX/Conceptual/BPRuntimeConfig/index.html

     

    MOSAからのお知らせと編集後記は割愛します

    MOSA Developer News   略称[MOSADeN=モサ伝]

    Apple、Mac OSは米国アップルコンピュータ社の登録商標です。またそのほかの各製品名等はそれぞれ各社の商標ならびに登録商標です。
    このメールの再配信、および掲載された記事の無断転載を禁じます。
    http://www.mosa.gr.jp/
    Copyright (C)2004-2006 MOSA. All rights reserved.