iPhone SDK、Objective Cが持つ「進化する能力」の遺伝子
2008.03.09
Objective Cの勉強から始めなければならないiPhone SDKは、いきなりコードを書き始めることが出来ない点が少しもどかしい。しかし、C++に関しては最初の商用コンパイラが出たころからの付き合いだが、Objective Cに関してはまったく付き合いがなかった私としては、結婚20年にして初めて浮気をするかのようなドキドキ感とともにObjective Cとの最初のデートに臨んでいる、という感覚。
すなおな目でObjective Cを見なければならないのにも関わらず、ついついC++と比べてしまう私。個々のシンタックスの違いに目を奪われつつも、言語仕様の背景にある設計思想を読み取ろうとする行動は、外見だけに捕われず彼女の中身を理解しようとする行動と同じ。
そんな中でちょっと気にかかったのが、categoryという既存のクラスを拡張する仕組み。言語仕様を見ただけでは、いまいち存在意義が伝わって来ないのだが、ここらあたりにC++とObjective Cを本質的に隔てる「何か」がありそうだが...。
その予感が的中していたことは、Appleが提供しているUIKit(iPhone用のUIフレームワーク)のチュートリアル・ビデオを見ている最中に判明する。そこに"hello"という文字列変数(型はNSString)を表示するサンプルが出て来るのだが、そのコード、
[hello drawAtPoint:location withFont:font] // C++の hello.drawAtPoint(location, font)に相当
を見て「あれ?」と思った。NSStringは、Mac OSと共通のCocoa Foundationという下位レイヤーで定義されたクラスの一つ。それがなんでiPhoneだけに存在するUIKitという上位のレイヤー向けのメソッド"drawAtPoint"をサポートしているのだろう、と。
その疑問は、NSStringの定義されているヘッダーファイルを見てすぐに解決した。NSStringというクラスそのものはFoundationで定義・実装されているのだが、drawAtPointというメソッドはUIKitがcategoryの仕組みを使って「追加」しているのだ。これは、RailsがRubyが提供しているシステムクラスを拡張し、jQueryがJavascriptが提供しているシステムクラスを拡張しているのと全く同じ発想だ。
つまり、Objective Cは、上位のフレームワーク(もしくはサブシステム)で下位のフレームワークが提供しているクラスを拡張することを可能にするcategoryにより、不必要なサブクラス(例えばGraphicsAwareStringクラス)の導入や、スパゲッティコードの元凶である「下のレイヤーから上のレイヤーへの依存」なしにクラスを使う人の利便性を上げることを可能にしているのだ。
地球上にこれだけバラエティのある動植物が反映しているのは、生物が進化の過程で「進化を容易にする」仕組みを獲得したことによる(雌雄に分かれて遺伝子を交換しあう仕組みなど)が、その意味では、このcategoryはObjective Cの進化を容易にするという意味で重要な役目を果たしているような気がする。
考えてみれば、90年代にOSの大改造に失敗したAppleはWindows95の成功にあやうく倒産の危機にまで合うことになったが、今度はVistaでOSの大改造の失敗したMicrosoft(Microsoftは当初、すべてのシステムAPIを.Net VM配下のマネージドAPIにしようと計画していた)がAppleに大きく遅れを取っているという点は以外と気がついていない人が多い様に思う。iPhone OSはまさにその成果と言える。