スキップしてメイン コンテンツに移動

Cocoa/Objective-Cの手習い

Objective-Cをちゃんと勉強して来なかったので、ここらでちゃんと勉強しようかと思いたった。まずは手習いとして、結城浩氏の『Java言語で学ぶデザインパターン入門』の各パターンでも移植してみよう。コード自体の意味や内容についてはそちらを参照してほしい。

第一回はIteratorパターン。 Objective-CではFoundationにIteratorを実装したNSEnumeratorが提供されているが、敢て実装してみる。

Objective-C自身は、オブジェクト指向の部分はC++などと違ってSmalltalkに近く、純粋に「らしい」コードを追求すればもっとよいコードがあるだろう。まず、JavaでいうInterfaceのようなものはないし、動的な指向が強く全てのオブジェクトがNSObjectというクラスに辿れるので本当はもう少し柔軟なコードが簡単に書けそうな気がする。が、ここは手習いなのでJavaのコードに準じたコードにしてみた。

まず、Javaのインターフェイスとして定義されているIteratorAggregateはObjective-Cでは少し異端とも思える静的な型付けを意識したProtocolを用いて以下のようなコードとする。

Iterator.h

    @protocol Iterator
    -(BOOL)hasNext;
    -(id)next;
    @end

Aggregate.h

    @protocol Aggregate
    -(id <Iterator>)iterator;
    @end

これら抽象クラスの実体としてBookShelfIteratorBookShelfを用意する。それぞれの宣言は以下の通り

BookShelfIterator.h

    @interface BookShelfIterator : NSObject <Iterator> {
        BookShelf* bookShelf;
            int index;
    }
    -(id)initWithBookShelf:(BookShelf*)shelf;
    @end

Aggregateの中での集合の扱いはNSMutableArrayを使用する。

BookShelf.h

@interface BookShelf : NSObject <Aggregate>
{
    NSMutableArray* books;
    int last;
}

-(Book*) getBookAtIndex:(int) index;
-(void) appendBook:(Book*)book;
-(int)getLength;
-(id <Iterator>) iterator;
@end

で、BookShelfIteratorIteratorとしてインターフェイス部分の実装は以下のような感じ

-(BOOL)hasNext
{
    if(index < [bookShelf getLength]) {
        return TRUE;
    } else {
        return FALSE;
    }
}

-(id)next
{
    Book* book = [bookShelf getBookAtIndex:index];
    index++;
    return book;
}
@end

Javaの例に即したテストコードは以下のようになる。 Book* book;

    book =  [[[Book alloc] initWithString:@"Around the World in 80 Days"] autorelease];
    [bookShelf appendBook: book];
    book =  [[[Book alloc] initWithString:@"Bible"] autorelease];
    [bookShelf appendBook: book];
    book =  [[[Book alloc] initWithString:@"Cinderella"] autorelease];
    [bookShelf appendBook: book];
    book =  [[[Book alloc] initWithString:@"Daddy-Long-Legs"] autorelease];
    [bookShelf appendBook: book];

   id <Iterator> it  = [bookShelf iterator];
   while([it hasNext]) {
        Book* book = [it next];
        NSLog(@"%@",[book getName]);
   }

   [bookShelf release];

恐らくProtocolを使う必要性は低いのだろうが……

デザインパターンの部分は余り考えることもなく終ったが、Javaのプログラマーが嵌りそうなところは、メモリー管理関連。いまではガベージコレクションもサポートされているが、デフォルトではプロジェクトの設定でオフになっている。自身でやるときは、自身でのretain/releaseautoreleaseを上手く意識して使うことが必要。

また、Cocoa/Foundationのクラスでは、[[Hogehoge alloc] init]で初期化すると普通にretain/releaseが必要だが、[Hogehoge hogehoge][Hogehoge hogehogeWithString]などのネーミングの初期化はautoreleaseが掛っている。なので、これらのオブジェクトはそのように扱わなければならない。また、GUIでなくコマンドラインのプログラムの場合、NSAutoreleasePoolが用意されない。Cocoa/Foundationのライブラリでは先の例のようにNSAutoreleasePoolを前提にしているものがあるので、自身で以下のように用意しなけばならない。

   NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

     // プログラムの処理

  [pool drain];

最初これに気付かずに悩んでしまった。
もっとも、XCodeで新規プロジェクトを作成する際、「Command Line Utlity」 のなかから「Foundation Tool」を選んで作成すれば、このあたりのコードは 埋まったテンプレートを用意してくれるのだが。

次はAdapterかな。

増補改訂版Java言語で学ぶデザインパターン入門
結城 浩
ソフトバンククリエイティブ
売り上げランキング: 5728

コメント

このブログの人気の投稿

W-ZERO3 カスタマイズ関連

Advanced/W-ZERO3[es]のカスタマイズのメモ。 いろいろインストールしているうちに何をどこから持ってきたのかわからなくなりそうなので、メモを残しておく。 ctrlwapmini テンキー関連の文字入力方式を改善するソフト。 キーマップの作成で携帯電話風の入力方式を利用できたりする。わたしはAuのカシオ系に慣れてしまったので、 w42ca風のキーマップ を拾ってきて利用している。 入手先: http://hp.vector.co.jp/authors/VA004474/wince/wince.html gsgetfile.dll 標準のファイル選択ダイアログを置換するDLL。 My Documents以外のフォルダにアクセスするために作成されたものらしい。いろんなソフトで前提になっているので、とりあえず導入しておく。 入手先: http://www.geocities.co.jp/SiliconValley-Cupertino/2039/ Multi Key Hook 標準では一つしか使えないキーフックを複数のアプリに割当で着るようにするソフト。 入手先をダウンロードし、Windowsフォルダにぶち込んでおく。 入手先: http://geocities.yahoo.co.jp/gl/hou ming 2/view/20070906/1189012118 DefaultMailer advanced/W-ZERO3[es]には、W-ZERO3メールとOutlookメールが入っているが標準MUAをどちらにするか切り替えるソフト。 標準ではOutlookとなっているが実際にはW-ZERO3メールを使うことの方が多いので、todayCompactなどから起動する際、このソフトを利用してW-ZERO3メールが起動するように調整。 入手先: Andante:DefaultMailer version 0.1.0.0リリース KeyLockSuspender 側面のキーロックスイッチの動作をカスタマイズできるソフト。 これでキーロックに連動して、画面のオンオフ、サスペンドなどを強制的に行いバッテリーの不要な消耗を防ぐ。 入手先からダウンロードして適当なフォルダに展開したら、ショートカットを作成してスタートアップに入れておく。 入手先: KeyLockSuspend...

Thinkpad T42

新たに購入したお仕事用のPC Thinkpad T42が先週末届いた。 仕様は、Pentium-M 1.80GHz, 1400x1050の15型TFT液晶、メモリーは追加して1.5GB(増設用に2GBを用意していたが、秘書さんのPCが256MBで苦しんでいたので1GBあげてしまった)、指紋センサー付き。無線もEEE802.11a/b/g対応となった。 こうして、iBookと並べてみると対照的。天使と悪魔か…… 今まで使用してたT30と比較すると、多少CPUが早くなりUSBが2.0になり指紋センサーがついて、やけに軽くなった。腰痛持ちの私にとっては、重量がぐんと軽くなったのが一番うれしいか。それでも2kg以上あるが。 指紋センサーはパームレスト上に(写真でいうと右側)実装されている。付属のソフトで設定すると、起動時のBIOS、HDDのパスワード投入、WindowsXPのログイン用パスワード投入の代わりに、電源オン時の指紋照合一発で済ませることができる。センサーに読み込ませるためには、指を一定の角度でセンサーに向けてまっすぐに動かさないと誤認識される。多少コツが必要で偶に失敗する。指紋はいくつか指を登録できるので複数を登録しておいたほうが無難。 今回も新しいおもちゃになりそうな機能はいくつかついているのだが、2日くらいで飽きてしまった。仕事で使うには十分なスペックで、十分に快適。ちょっと前まではお仕事用のPCも結構愛着やこだわりを持っていたのだが、買い替えを行って新しいPCが来てもあまりワクワクしなくなった。最近は、2年に一度機械的に買い替えを行うような感じ。スペック的に見るとiBookなどと比べるまでもないほどはるかに重装備だが、iBookのほうが楽しい。 PCの価値はスペックだけでは語れないのだよ(ムスカ風)