Objective-Cの配列
Objective-Cと配列についてメモ。ほとんどこれは愚痴なんだが...
まず、Objective-Cでは、生の配列(int xxx[]; みたいに作るやつ)はあまり使う局面はない。プレーンCと同様、配列サイズがコンパイル時に決定できるときにしか使えないし、オブジェクト配列のとき各要素にreleaseするのが手動だからだ。JavaやC#の配列はサイズは実行時に決定すればよい(実行時に変化させることができないだけ)ので、この差は大きい。
なので必然的に配列オブジェクトを使うことになる。iPhoneOS/MaxOSXのプラットフォームでは、ご丁寧に配列用のクラスは2種類用意してくれている。NSArrayとNSMutableArrayだ。名前を見て分かる通り、配列の中身を変更できるのはNSMutableArrayだけで、NSArrayは構築時に全要素を決定できる場合にしか使えない。
ところが、「構築時に全要素を決定できる」という縛りを実現するために、コンストラクタで全要素を放り込むAPIしか用意されていないのである。
可変個引数で、
[[NSArray alloc] initWithObjects:a, b, c]
みたいな感じだ。いやこれじゃ、依然としてコンパイル時にサイズが決定できる場合にしか使えねーじゃん。あとはCの生配列から初期化するくらいしかできないが、結局「配列作成の実行時にサイズが決まり、あとは変化しない」配列を作るのにはまるで役に立たん。
なので仕方なくNSMutableArrayを使うことになる。ところが、セレクタ名は長くなりがちなので、ちょっとした配列操作のためにもえらく文字数を消費する。Java/C#なら
a[i] = b;
で終わる簡単な代入ですら、
[a replaceObjectAtIndex:i withObject:b];
と書かにゃならん。げげ。まあXCodeにもインテリセンスはついているのでこれをフルにタイプする必要はないが、でもなんだかなあ。
あと他の不満としては次がある。
* 配列要素にnilがあってはならない(そうしたい場合は少ないが、たまにはある)
* 配列要素はすべてid型(タイプセーフにするのはカテゴリとマクロで下のようにすれば何とかなるが、プリミティブ値が直接突っ込めないのでint[]相当のことをやらせるためにNSValueを使わないといけないのはつらい)
#define TYPESAFE_ARRAY_DECL(TYPE, SELKEY) \
@interface NSMutableArray ( SELKEY ) \
-(TYPE*) get##SELKEY##At:(int)index; \
-(void) set##SELKEY##At:(int)index value:(TYPE*)value; \
@end
* Linked Listが標準ライブラリにないのは勘弁してほしい。そういえば.NET Frameworkも初期バージョンはそうだった。ソフトウェアの何十年の歴史において、本質的なデータ構造は配列・リスト・ハッシュテーブルのたった3つしかない(注:treeはリストの一種とする)んだから、これが1つでも欠けるのは困る。
* XCodeのインテリセンスはもうちょっと賢くなってほしい。型を見ているような見ていないような微妙な挙動をする。
* 少し複雑なマクロを書いているとXCodeのエディタがよくクラッシュする。VisualStudioやEclipseに比べるとXCodeはちょっといまいち。
開発作業は進んでいるが、少し作業するとすぐ分からないこと/気になることがでてきて、それを調べる寄り道が多い。特に、調べものをしてるうちにWikipediaに辿り着いた場合、関係ない分野にもたくさんリンクが張られているのでついクリックして読んでしまう。昨日も、Objective-Cのことを調べていたはずなのに気がつくとなぜかナチスドイツ陸軍の戦車の記事を読んでいたぜ。
他にも、後で便利なように小技マクロやクラスを書いたり、そのテストケースを書いたらまた調べたいことが出てきて、そのうちに別のアプローチを思いついてコード書き直して実験して...の繰り返し。Yak Shavingってのはこれのことだな。
| 固定リンク
トラックバック
この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/73665/42136705
この記事へのトラックバック一覧です: Objective-Cの配列:




コメント
配列が使えないっていうのがよく分からないんですが、
cでもobjective-cでもmallocすればJavaと同等に使えるんじゃないですか。
投稿者: 通りすがり (2008/12/30 22:37:17)