MOSA Multi-OS Software Artists

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

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

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

2005-10-11

目次

  • 「WebObjects Dev Report」     第25回  田畑 英和
  • 藤本裕之のプログラミング夜話 #78
  • 高橋真人の「プログラミング指南」  第76回
  • ニュース・解説                小池 邦人

「WebObjects Dev Report」  第25回  田畑 英和

Reusable Componentの最適化

 さて今回はReusable Componentの続きです。前回はコンポーネントのインスタンスを共有化する次のメソッドを紹介しました。このメソッドを実装したコンポーネントは1度しかインスタンス化されず、アプリケーション内で共有されるため、メモリの消費量を抑えることができます。

     public boolean isStateless() {
         return true;
     }


 Reusable Componentを最適化する方法としては次のようなコーディングも有
効です。

     public boolean synchronizesVariablesWithBindings() {
         return false;
     }


 Reusable Componentは、Dynamic Elementのように親コンポーネントから値をバインドすることができ、デフォルトの状態ではバインドしたデータのコンポーネント間でのやりとりは自動的に行われます。
 つまりコンポーネント間でのデータの同期が自動的におこなわれるわけで、もちろん自動的にデータをやりとりさせておけば、コーディングをおこなう必要もないので便利なのですが、上記のコードを追加することによりこの自動同期を停止することができます。この場合、データの同期をおこなう処理をコーディングしなければならないのですが、自動でデータの同期をおこなう場合に発生するオーバーヘッドを抑えるとともに、コンポーネント間でのデータのやりとりを完全にコントロールできるようになります。
 自動同期を停止することにより、必要に応じて親コンポーネントからデータを取得したり、親コンポーネントにデータをセットしたりすることができます。具体的にはReusable Componentにおいて次のようなコーディングをおこないます。

     public String value() {
         return (String)valueForBinding("value");
     }

     public void setValue(String value) {
          setValueForBinding(value, "value");
     }


 ここでは”value”というAttributeに対してバインドをおこなっているとします。value()が実行された場合は、親コンポーネントで”value”にバインドしてあった値を取得してreturnします。setValue()が呼び出された場合は、引数の値を親コンポーネントにセットします。これで親コンポーネントとのデータのやりとりが自由にできるようになります。
 データの入力をともなわないReusable Componentの場合は、getterメソッドだけを実装しておけばよいですし、データ入力をともなう場合はさらにsetterメソッドも追加しておく必要があります。

 あとはReusable Compopentを新規作成するたびにisStatless()とsynch…()を追加すればよいのですが、毎回追加するというのも手間がかかりますので、あらかじめこれら2つのメソッドを実装したクラスを作成(WOCompoentを継承)しておき、あとはそのクラスを継承して各Reusable Componentを作成すれば手間を省くことができます。

Reusable Componentのネスト

 Reusable Componentを別のReusable Componentに組み込んで使用することもできます。つまりコンポーネントのネストができるわけですが、ネストすることによりさらにコンポーネントを細分化していくことができます。
 たとえばタブをもったメニューがあり、複数の画面で使用されているとしましょう。このときまず各画面で共通しているタブメニューの部分だけを1つのコンポーネントとして実装し、各画面から共有することができます。
 タブメニューは、タブが繰り返し表示されて並ぶインターフェイスになっています。このとき各タブは異なる画像を使用したり、タブをクリックしたときに呼び出すactionメソッドはタブごとに異なっていたりしますが、タブごとに画像をもっているということと、actionメソッドを呼び出すということは共通しています。
 そこで汎用的なタブコンポーネントを作成し、実際に使用する画像やactionメソッドをバインドにより指定するようにすれば、タブを再利用することができます。このときコンポーネントの関係は次のようになります。

・コンポーネントの関係
 親コンポーネント > タブメニューコンポーネント > タブコンポーネント

 このようにまず各画面に共通している部分はコンポーネント化するということと、さらに繰り返し表示されるような部分もコンポーネント化してしまうというのがReusable Component作成のポイントになります。 
 慣れないうちはどのような単位でコンポーネントを切り出していったらよいか分からないかもしれませんが、ページのなかにあるパターンを見極めてコンポーネント化していきましょう。

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

 前回は、NSWindowの初期化メッセージ、

-(id) initWithContentRect:(NSRect)contentRect
              styleMask:(unsigned int)aStyle
                backing:(NSBackingStoreType)bufferingType
                  defer:(BOOL)flag;


の解説の途中、最後の flag について書いているところで時間が……ぢゃない紙数が尽きたんだった。この flag 、ウィンドウの描画に関わる命令の実行を、実際にウィンドウがスクリーンに持って来られるまで延期するどうかを指定するもんだった。
 これを延期できると何がいいのか。簡単に言うとアプリケーションの起動が速くなるのである。始めから終わりまで、煮ても焼いても(そんなことをするヒトはいないが)一個しかウィンドウを出さないプログラムもあるかも知れないが、普通のアプリというのはあーだこーだといろいろなウィンドウがあるもんだ。でしょ?
 その中には……例えば「そのアプリについて……」メニューで表示されるアバウトボックスみたいに、通常のセッション(一個のアプリが起動してから終了されるまで)では一度も表示されないことが多いモノもあるわけ。しかしながら、そういういわば出番のないウィンドウも、きっちり起動時に楽屋を用意されてメイクアップをして弁当も食ったりする、当然ながらその分CPUタイムも食う、と。
 この flag をオンにしてウィンドウを初期化しておけば、世に名高いトヨタのカンバン方式が実行されて、楽屋入りしてメイク……てな作業はいざ画面に出る直前に行なわれる。食ってる暇がないから弁当も出さなくて済む(笑)。その替わり当のウィンドウが開く時、ちょっとだけ時間がかかるけど、という……こういう話である。

 defer flagの話が長くなってしまったが本題に入る。覚えてますか、前回ワタシが提示した問題は、「そうは言うがこの初期化メッセージ、通常あんまり使わないよな」ということであった。それは何故でしょうと、実はこれが本題。……まぁ答えは簡単で、つまり普通のウィンドウは Interface Builderで定義できちゃうので、わざわざこのメッセージを使ってプログラム中で作る必要はないってことなんだけど、ではInterface Builderで定義できない「普通ぢゃないウィンドウ」って例えばドンなもんか、と話を進めたい。
 もしそうできる環境でこれを読んでいたら、是非 Interface Builderを起動し、新しいウィンドウを一個作ってみてほしい。上の初期化メッセージに渡される引数のうち、contentRect、bufferingType、そして最後の flag の内容はここで指定できることが分かるはずだ。contentRect は画面上のそのウィンドウの位置とサイズそのものだし、bufferingTypeは「window backing」という見出しに続くラジオボタンで指定できる。defer の flag に当たるのはその下に並んだチェックボックスのうちの「Deferred」というヤツだろう。……もうおわかりか、そう、aStyle だけが指定できない。いや、正確には以下の指定出来うるすべての値(前回も出したが)

enum {
    NSBorderlessWindowMask = 0,
    NSTitledWindowMask = 1 << 0,
    NSClosableWindowMask = 1 << 1,
    NSMiniaturizableWindowMask  = 1 << 2,
    NSResizableWindowMask = 1 << 3
};

のうち、「NSBorderlessWindowMask」だけがどうあがいてもここでは設定できないのである。つまり、InterfaceBuilder ではタイトルバーのないウィンドウは作れないのだ。
 というワケで、次回はなんでタイトルバーのないウィンドウなんか作りたいのか小一時間……ぢゃなくて(笑)、タイトルバーのないウィンドウの作り方を解説しようと思う。ほんぢゃ。
(2005_10_06)

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

UNIXとしてのMac OS X

〜Perlについて(22)〜

 こんにちは、高橋真人です。
 前回まででほぼ正規表現の記述に必要な要素に触れたので、今回から検索置換の「置換」つまり正規表現を使った文字の置き換えについて説明します。
 今までは正規表現の実例を出してもほとんどが、マッチした部分の消去か出力ということでした。しかしこれに「置き換え」という処理が加わると、途端に正規表現を使うメリットが広がってきます。
 正規表現を使った置換処理の場合、マッチした全体を単純な文字列に置き換えてもよい(例えば、改行コードの変換などといった処理はこれで行けます)のですが、パターン表現の中で丸カッコを使った「グルーピング」を施すことで、マッチ結果に応じた処理ができるようになるのです。
 まずは丸カッコを使ったグルーピングについて説明します。正規表現では多くのプログラミング言語と同様に結合の優先順位を変えるためにカッコを使うことができます。例として以下のような正規表現を見てください。

/b|peach/

 bとpの間にある縦棒の演算子は、C言語でもおなじみのOR演算子で、この演算子を挟んでいる「どちらか」ということを表します。従ってこの正規表現はbeachとpeachにマッチし、/[pb]each/という正規表現と同等と言うことができます。
 では、これを応用してpeopleとappleという2つの単語の両方にマッチさせたい場合にはどう書けばよいでしょうか。

/peo|apple/

 最初は、こういう書き方をしてしまう人が結構います。ですが、残念ながらこれでは意図した通りにはなりません。| 演算子の優先順位は直前と直後の文字にしか及ばないために、この場合「oかa」という意味になってしまうのです。よってこの正規表現がマッチするのは、peoppleとpeappleということになります。
 そこでカッコの登場です。結合の優先順位というのがピンと来ない人もいるかもしれませんから説明しますと、正規表現においては個々の文字(もしくは文字表現)が一つずつそれぞれに式の要素を形成していると考えます。従って、/cat/という正規表現を無理矢理C言語の式に置き換えると、以下のように表すことができます。

char s[4] = "cat";
if (s[0] == 'c' && s[1] == 'a' && s[2] == 't') {
     // マッチした
}


 つまり、c、a、tという文字列の構成要素を一つずつ検証して、すべての条件が成立した場合(もちろん、それぞれが順序通りに連続して並んでいる必要があります)に、はじめてマッチしたということになるわけです。
 それでは/peo|apple/を無理矢理Cで表現してみます。

if (s[0] == 'p' && s[1] == 'e' && (s[2] == 'o' || s[2] == 'a') && s[3] == 'p' && s[4] 
== 'p' && s[5] == 'l' && s[6] == 'e') {
     // マッチした
}

 こんな感じになります。このCの式に基づいて元の正規表現を「結合関係をより明確になるように」表記し直すと、/pe(o|a)pple/となります。こう書くと、意図通りになっていないことがより分かりやすいのではないでしょうか。
 さて、ここまで分かればもう簡単です。peopleとappleにマッチさせるためには、カッコを使って結合をコントロールしてやればいいのです。答えはこんな感じです。

/(peo|ap)ple/

 これで、見事に正規表現が意図した通りに機能するようになります。

 このように、丸カッコを使うことで文字表現の結合関係をコントロールすることができることはお分かりいただけたと思いますが、実は正規表現の丸カッコにはもっと重要な役割があるのです。それは、上記のように丸カッコを使って囲った部分が特定の記憶領域に記憶されるという「副作用」です。次回はその中身を見ていきましょう。

ニュース・解説

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

Carbon ドキュメント & サンプル & SDK ナビゲーション(2005/10/7)

【開発環境】

長い間熱望されていたMOSA会員専用掲示板が開設されました。会員相互の交流、技術情報の交換に大いに役立つと思われますので、皆さんバリバリ活用しましょう! ひとつの質問スレッドが、多くのMOSA会員にとって大変有用な情報源になると思います。どんな簡単な内容でも気にする必要はないので、ぜひ数多くの質問を書き込んでください。現在はQ&Aを中心に、初心者向けと一般向けの2つの会議室が技術的な話題の中心ですが、将来的に利用頻度が増え、色々な技術分野の会議室(Webとか3Dとか)が増設されて行けば、より面白くなるでしょうね!

なにせアップル社へひとつ質問をすると、その正式な回答を得るためにかなり高額な費用が発生します。また、その質問内容がバグに関係していると、アップル社から「逃げ道的」や「裏技的」な回答を得られるかどうかは定かではありません(笑)。MOSA掲示板には、現場の最前線で活躍されている数多くのMacデベロッパーの方々が参加されています。「バグは会議室で起こっているのではない!」ということで(笑)、MOSA掲示板からは、アップル社とはひと味もふた味も違った的確なアドバイスを期待できるのではないでしょうか!

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

前回から10月7日の期間中、Apple社のDocumentationサイトには数多くのドキュメントが登録されました。ただし、大部分は内容のマイナーチェンジです。今回は、その中で初版と内容が大幅変更になったドキュメントだけをピックアップしておきます。Mac OS Xになってから行方不明になっていた「AGL Programming Guide」(Carbon用のOpenGL環境の解説)の新版が、やっとこさ登録されました、また、前回紹介した2つのリリースノートの改訂版が登録されましたので、関係者は内容をチェックしてみてください。デベロッパー向け読み物の方は2つ登録されました。「Taking Advantage of the Accelerate Framework」では、AltiVecコードを記述せずに画像処理などを高速にするのには、どのようなAccelerate Framework APIを利用したら良いのかを紹介しています。「Scoping Your Transition Projects」の方は、前号の木下さんの記事を参照してみてください。

「AGL Programming Guide」(PDFあり)(初版)
「Bonjour Overview」(PDFあり)
「Deploying Mac OS X Server for High Performance Computing」(PDFあり)(初版)
「DNSServiceDiscovery API Reference for C」(初版)
「DNSServiceDiscovery Programming Guide」
「FWAUserLib Reference」(初版)
「Miscellaneous User Space API Reference」(初版)
「NSNetServices and CFNetServices Programming Guide」(PDFあり)(初版)
「Writing PCI Drivers」(PDFあり)
「Xsan Tuning Guide」(PDFあり)(初版)

http://developer.apple.com/documentation/index-rev-date.html

リリースノート

「J2SE 5.0 Release 1 for Mac OS X Release Notes」(マイナーチェンジ)
「WebObjects 5.3 Release Notes」(マイナーチェンジ)

http://developer.apple.com/releasenotes/

「Taking Advantage of the Accelerate Framework」(読み物)

http://developer.apple.com/performance/accelerateframework.html

「Scoping Your Transition Projects」(読み物)

http://developer.apple.com/transition/projectscope.html

前回から10月7日の期間中、新規テクニカルノートはひとつだけ登録されました。また、新規テクニカルQ&Aの方は5つ登録されています。TN2143は、以前に登録された物の改訂版です。テクニカルQ&Aについては、QA1378のみが初登録となり、それ以外の物は内容が改訂(Mac OS X 10.4に対応するためなど)されて再登録されています。

TN2143「Getting images in and out from Quartz Composer compositions」

http://developer.apple.com/technicalnotes/index-rev-date.html

QA1037「CGBitmapContextCreate Supported Color Spaces」
QA1396「Creating color spaces that ensure color matching.」
QA1413「QuickTime for Windows returns bdNamErr (-37) error with long Windows file name」
QA1378「StopAlert and NoteAlert now use the Application icon」(初版)
QA1438「Using the QuickTime DVCompressor properties」

http://developer.apple.com/technicalqas/index-rev-date.html

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

前回から10月7日の期間中、Apple社のSample Codeサイトには、新しいサンプルソースコードが8つ登録されました。このうち初登録されたサンプルは、「DisplayURL」と「QTQuartzPlayer」と「tcplognke」の3つのみです。

「AudioCDSample 」(Core Audio関連)
「CocoaInCarbon」(Carbo&Cocoa関連)
「ComboBoxPrefs」(Carbon関連)
「DisplayURL」(Carbon関連)(初版)
「filesystem_example」(Carbon関連)
「HelpHook」(Java関連)
「QTQuartzPlayer」(Cocoa&QuickTime関連)(初版)
「tcplognke」(Divice関連)(初版)

http://developer.apple.com/samplecode/index-rev-date.html

【デベロップメント SDK】

前回から10月7日の期間中、Apple社のSDKサイトには新しいSDKがひとつも登録されませんでした。

http://developer.apple.com/tools/download/

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

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