NSArrayとNSTableViewとNSArchiverを学ぶ
どのクラスも、まぁ、その名前の通り。NSArrayは配列を、NSTableViewはテーブルビュー(Winで言う所の、エクスプローラで表示方法を「詳細」にした時に表示されるような形式)を、そしてNSArchiveはデータの保存に関するクラスである。
Windowsに関するプログラミング技法は全然知らないので比較はできないが、とにかくどのクラスも便利過ぎる。「この値を格納しろやー」「このデータを『商品名』フィールドに表示してくれやー」というメッセージを、それぞれのインスタンスに送るだけで、きっちりと期待通りの動作をしてくれる。
何より凄いのが、NSArchive。各オブジェクトに -encodeWithCoder: プロトコルを実装してやれば、保存したいオブジェクトに含まれる、別のオブジェクトまでを全て一発で保存してくれる。そうやって保存したデータの読込みは、NSUnarchiver クラスで一発OK。面倒な保存/読込み処理を、これらのクラスに丸投げできて、非常に便利便利。
前回のNSSoundとあわせて、簡易サウンドプレーヤを作る為の材料は、これで揃った。あとは実際に製作に取りかかるのみだ。頑張るぞー!!
メソッドのポインタ
Objective-Cのメソッドのポインタを取得して、メソッドをCの関数として呼び出す事が出来るのだとか。
// イニシャライズ id obj = [Hogehoge new] ; // メソッドのセレクタ取得 SEL method = @selector(methodOfHogehoge); // セレクタからメソッドのポインタ取得 IMP func = [Hogehoge instanceMethodFor:method];<br /> // 関数としてメソッド methodOfHogehoge を実行 func(obj, method);
肝となるのは、instanceMethodFor: メソッド。こいつがセレクタ(メソッドの内部識別子)から、メソッドのポインタを探し出してくれる。その返り値を、IMP型で受け取るとあら不思議、Cの関数呼び出しの形でObjective-Cのメソッドが実行できちゃった。ただし、引数として元のメソッドが含まれるオブジェクトのインスタンスと、メソッドのセレクタを渡してやらないといけない。
とりあえずObjective-Cの勉強は一段落したが、俯瞰してみるとObjective-Cが「Cの枠組みの中でオブジェクト指向を目指した言語」であるということがよくわかる。そのお陰かCの流れを汲んだオブジェクト指向言語であるC++と比べて、言語規模は格段に小さい(と思う)。
表記方法がかなり特殊ではあるが、初心者がオブジェクト指向を学ぶには、Objective-Cは結構いい言語なのでは?と思ったりした。
イニシャライザの返り値
サンプルソースを見ていると、各クラスのイニシャライザは
return self;
や
obj = [super init] ... return obj;
というコードで、自身を返している。うーん何でだろう?
わが師匠し~くる氏に聞いてみたところ、
[hogeHoge alloc]; [hogeHoge init]
が
[[hogeHoge alloc] init]
と短縮して書ける。そして「親クラスのイニシャライズが成功したか否かの判別に使う」とのこと。
ふーむ、最初の用途は簡単に理解できる。[hogeHoge alloc] が自身(self)を返すから、[[hogeHoge init] alloc] = [self init] = [hogeHoge init] ということが言える。
でも、親クラスのイニシャライズの判別は、ちょっとわからない。なぜ、self にスーパークラスの返り値を入れることで、判別できるのだろう……?そもそも、親クラスのイニシャライズの成否を調べる場面が、今は思い浮かばない。
まぁ、ボチボチ調べていくことしますか。
(2013-04-10 追記)
今読み返してみると、内容が完全に「日本語でおk」な件。当時の俺は何を考えていたんだろう…。
GNU版Objective-Cのコンパイル
GNUのObjective-Cランタイムを使ったソースをコンパイルするには、gccに「-lobjc」オプションが必要。
最初、これがわからずに「『Object』なんてクラスしらねーよ」って、リンカに怒られてた('A`)。