最大の特徴はオブジェクトシステムが完全に動的という点で、実行時のクラス拡張、オブジェクト汎用型idの導入により型によらない動的配列・辞書など、インタプリタに近い記述力をもつことである。実際にコードそのものはネイティブコンパイルされるものの、動作原理はほぼインタプリタに近く、コンパイラ型言語としてはまれな柔軟性を発揮する。
したがって、C側から見れば一種のスクリプトインタプリタが乗っているような状態であり、逆にオブジェクトシステムからはOS機能や膨大なC言語資源を直接利用可能なインターフェースが備わっているといえる。また仮想マシンを持たずに済むため、取り回しも良い。パフォーマンスはJavaのような中間コード型言語よりも良好で、CやC++のようなネイティブコンパイル言語には劣るとされる。Objective-C特有のこの形態は双方のメリット・デメリットが明確で、実際的な使い勝手が非常に優れている。この特性に着目したのがNEXTSTEPで、UNIXとの互換性と先進的なオブジェクト指向環境の両立に成功し、その後のOS設計に大きな影響を与えることとなった。
後続言語への影響としては、特にJavaの基礎設計にその姿を見ることができる(サン・マイクロシステムズがOPENSTEP開発を共同で行なっていたことと関係がある[1])。
オブジェクトシステムの概要クラス単一継承+インタフェース多重継承(プロトコル) 通常はルートクラスから継承 Objective-Cは、1983年にBrad Cox
オブジェクトシステム動的束縛、メタクラスを持つ
型動的型+見た目の静的型のハイブリッド
実行速度コードはCと同等のネイティブコンパイル、メソッド呼び出しは動的ディスパッチを行なうのでやや遅延する。平均してC/C++より多少遅く、中間コード型言語(Javaなど)より数倍程度高速といわれる。ただし、クリティカルな部分はいつでもCで書き直せるため、実行速度が問題になることはまずない。
その他オブジェクトはポインタ互換、Cのスカラー型はオブジェクトではない
歴史
そのマシンのユーザインタフェースは、Display PostScriptとObjective-Cで書かれたApplication Kitにより提供され、Objective-CはNeXTコンピュータの主力言語となった。その後の歴史は、主にNeXT社とともにあり、GCCをベースにしたObjective-Cサポートが行われ、プロトコルの導入など文法の拡張なども行われている。NeXT社による多くの成果は、GCCに還元されている。
1995年には、NeXT社がStepstone社からObjective-C言語と、その商標に関する全ての権利を買い取っている。1997年初頭、AppleがNeXT社を買収し、2001年に登場したMac OS XのCocoaフレームワークのコア言語として採用されている。Mac OS X v10.5からは一部言語仕様の変更が行われObjective-C 2.0と呼ばれる(詳細は#Objective-C 2.0を参照)。
コンパイラおよび言語仕様は完全に公開されているものの、長らくNeXTおよびその後継であるmacOSとiOSの専用言語に近い状態にある。2008年にiPhone OS(現iOS)のAPIが公開されて以降、習得者の人口が増える傾向にあるが、Appleの開発環境は、徐々にLLVM/Clangにシフトし、GCC版は事実上のGNUstep専用と化している。 C++とは異なり、オブジェクトのメソッド呼びだしにはSmalltalkのメッセージ式を模した新たな構文が導入されている。Objecitve-Cではこれをメッセージ式と呼び、メソッド呼びだしはメッセージ送信と呼ぶ。メッセージ送信は実行時のメッセージパッシングであり、その時渡されるメッセージ値をセレクタという。特徴的なのはSmalltalk同様キーワード引数形式をとることで、セレクタ名と引数値が交互に並んだ形態になる。なおSmalltalkにはあるカスケード式(一つのオブジェクトに続けてメッセージを送る)はない。// メッセージの送信// 単項メッセージ[receiver msg];// 引数付きメッセージ。この場合「msg:with:」でセレクタ一つval = [receiver msg: arg1 with: arg2];// メッセージの入れ子val = [obj1 msg: [obj2 msg]]; Objective-Cのクラスは定義部と実装部に分かれており、通常定義部を.hファイル、実装部を.mファイルに記述する。後述のカテゴリによりクラス定義を複数のパートに分割できる。// クラスの定義 (MyObject.h)@interface MyObject : NSObject{ int val; id obj;}+ (void)classMethod:(id)arg; // クラスメソッド- (id)method:(NSObject*)arg1 with:(int)arg2; // インスタンスメソッド。arg1は型付き@end// 実装 (MyObject.m)@implementation MyObject+ (void)classMethod:(id)arg{ // some operation}- (id)method:(NSObject*)arg1 with:(int)args2{ return obj;}// 典型的なinit- (id)init{ self = [super init]; // スーパークラスの呼びだし if(self != nil) { val = 1; obj = [[SomeClass alloc] init]; } return self;}// deallocは自身のリソースを解放してからスーパークラスに回す- (void)dealloc{ [obj release]; [super dealloc];}@end メソッドにはクラスメソッドとインスタンスメソッドがあり、それぞれ接頭辞+及び-により区別される。クラスメソッドはクラスオブジェクトの操作に、インスタンスメソッドはインスタンスオブジェクトの操作に使用される。クラスメソッドは特にインスタンスオブジェクトの生成にも使用される事が多い。インスタンスメソッドは、インスタンスオブジェクトにメッセージを送信した際に起動され、クラスメソッドはクラスオブジェクトにメッセージを送信した際に起動する。なお、インスタンスメソッドとクラスメソッドは全く同じ名前のセレクタを指定して定義できる。 いわゆるコンストラクタは存在しない。慣習として新規オブジェクトの生成は+allocで、初期化は-initで行われるが、プログラマが自由に別の特殊化したメソッドを定義することが可能であり、初期化中に別の初期化メソッドを呼びだす場合もある。
基本的な構文
メッセージ送信
クラス定義