待望のiPhone SDKが公開された。予想通り、アプリケーションの開発に使われるのは、Objective-Cと、iPhone用にカスタマイズされたCocoaである"Cocoa touch"だ。Objective-Cは、Objective-C 2.0相当のものが使えるようである。

Objective-CとCocoaの活躍分野は、Macだけでなく、携帯デバイスにも及ぶことになった。高い生産性を誇るこのコンビは、ますます重要度を増していくだろう。

今回は、プロパティにアクセスするためのドット演算子を紹介しよう。

ドット演算子

インスタンスのプロパティにアクセスするには、これもまた新たに導入された、ドット演算子を使う。ドット演算子は、C言語の構造体で使われている。内部の属性にアクセするということで、感覚的にはこれに近いだろう。

たとえば、nameというプロパテイを持つPersonというクラスを考えよう。このプロパティに、ドット演算子を使ってアクセスするには、次のようなコードになる。

リスト1

Person* person = [[Person alloc] init];
NSString* name = person.name;
person.name = @"Jobs";

これで、プロパティの取得および設定が行える。

ただし、表記はドット演算子であっても、実際はメソッドの呼び出しが発生することに注意してほしい。インスタンス変数に直接アクセスする訳ではない。したって、次のソースコードはリスト1と同等になる。

リスト2

Person* person = [[Person alloc] init];
NSString* name = [person name];
[person setName:@"Jobs"];

nameへのアクセスは、nameメソッドとsetName:メソッドの呼び出しと同じ、ということだ。このプロパティ名からメソッド名への変換規則は、キー値コーディングのものと同じになる。

ドット演算子

ドット演算子は、実体はメソッド呼び出しということだが、コンパイル時の取り扱いが異なる。そこのところを見てみよう。

まず、メソッド呼び出しを考えてみる。Objective-Cの場合、メソッドを呼び出したときに、そのメソッドが本当に実装されているかどうかのチェックは、実行時に行うというのが原則だ。したがって、id型のオブジェクトに対するメソッドの呼び出しは、とくにチェックも行われずすべてコンパイルは通る。オブジェクトに型が指定されている場合でも、警告は出るが、結局コンパイルは通ってしまう。

たとえば、先ほどのPersonクラスにlastNameというメソッドが実装されていなくとも、その呼び出しを行っているソースコードはコンパイルが通る。もちろん、このまま実行すれば、例外が発生して止まってしまうが。

リスト3

id person = [[Person alloc] init];

// 存在しないメソッドを呼び出す
// コンパイルは通る
NSString* lastName = [person lastName];

これに対して、ドット演算子ではもっと厳密なチェックを行うようになった。オブジェクトにドット演算子を適用すると、その型がチェックされることになる。存在しないプロパティが指定されていると、コンパイルは通らない。そもそも、id型のオブジェクトにドット演算子を適用することができないのだ。ドット演算子を使いたい場合、必ずキャストしてやらなくてはいけない。

リスト4

id person = [[Person alloc] init];

// id型のプロパティにアクセスする
// エラーになる
NSString* name = person.name;

// 存在しないプロパティにアクセスする
// エラーになる
NSString* lastName = ((Person*)person).lastName;

これをもって、プロパティは「コンパイル時での静的な型チェックを取り入れた」ということができるだろう。Objective-Cのような動的な言語は、その弱点としてコンパイル時のチェックが甘い、と言われ続けている。プロパティの取り扱いは、静的な色合いを取り入れている。

もっとも、動的な「ゆるさ」がObjective-Cの特徴であることも事実だ。プロパティを使用する場合、常にオブジェクトの型を意識して、かつそれをソースコードにキャストという形で記述しなくてはいけない。実際にプロパティを使ったプログラミングを行う場合、id型のオブジェクトに対してプロパティを適用したい場面は多い。たとえば、NSArrayから取り出したオブジェクトなどだ。このような場合、キャストをするとか、型を指定した変数に代入してやる必要がある。

ドット演算子は、コンパイル時のチェック機能を高めるという点では成功しているだろう。だが、もともとはソースコードの記述料を減らす目的で導入されたものだが、頻繁にキャストする必要があるので、結果として増えてしまっている。いささか、皮肉な結果になってしまったようだ。