ごきげんよう、ハイテクです。
さすがに投げっぱなしもナニなので、Objective-Cの説明もやっておきたいと思います。
Objective-Cとは †
Objective-C = C + Objective Runtime
以上。
というのも投げ過ぎな気がするので説明するに。
C言語にオブジェクト指向の概念を導入するにあたって
言語の仕様を変えたもの >>> C++
言語に沿って仕組みを追加したもの >>> Objective-C
な感じです。
元はどこかの学者がSmallTalkというのを参考にCの拡張をやらかしまして
コーラ売りのスカリーにAppleを追い出されたジョブズが立ち上げた
NeXTStepという会社、と同名の(ワークステーション気味な)コンピュータ。
ソイツに正式採用されたのが始まりの、まさにギークのためのマイナー言語。
しかしAppleが色々あって傾いて、次世代OSの開発に失敗し、とりあえず他から買うか的に
BeOSになりかけたはずがジョブズ復活でNeXTStepベースのMacOS Xが生まれ
継続して標準言語の立場を得たのが、最近の神がかってるAppleのシェア伸ばしと
あとはiPhone向けの唯一の開発言語と言う立ち位置により最近に人気。
ほんとなんか妙に元気ですよね、最近。2.0とか出ましたし。
閑話休題。
C++はクラスだのオーバロードだのなんだの
便利そうな機能のを盛りだくさんに沢山入れてくれやがりまして
それ故に色々にできるけど、スマートさに欠け、邪魔で面倒です。
対してObjective-Cは、C言語を生かし切った、ランタイムとしての実装です。
ラクチンな記述のために文法表現は多少に拡張された物の
それらはプリプロセッサによりC言語のコードに変換されます。
最低限の機能すらもライブラリとして外部に実装し、シンプルの極みを目指すC言語。
それを生かしてる感じがとても素敵じゃありません?
速さ †
Cよりは遅く、C++よりは遅く、しかしJavaなどよりかは比較にならず速い。
C/C++より遅いのはオブジェクトシステムのランタイムの処理のオーバーヘッド
(メソッド呼び出し毎に名前による解決が行われる)があるからで
しかしネイティブ動作する故にVM越しのJavaなどとは比較にならず速いです。
速度を稼ぎたい場合は
- 処理をC言語で書く
- メソッド呼び出しの中身を取り出し、関数ポインタ呼び出しする
- もちろんインラインでアセンブラかけます。
が主なやりかた。
Objective-Cの流儀としましては
- 面倒くさいが速度が優先されない部分はObjective-Cで。
- 処理の中心、高速化が必要な部分はCで。
と書き分けるのが、とても幸せなのです。
ダイナミックさ †
Objective-Cが他のオブジェクト指向言語と決定的に違うのは、それが動的な言語であるということです。
スクリプト言語ならばともかく、そうでなくこんな特性を持ってるのは激レアです。
全てのオブジェクトは、日常的にid型で受け渡しされます。
それというのはJavaで言うところのObject型ですね。
そう、あの、Javaが嫌って嫌って仕方ない、自己矛盾の象徴たるObject型です。
JavaはObject型が大嫌いで、なにかと他の型に入れたがる習性がありますが
Objective-Cはそうではないのです。寛大な心で言うのです。
型なんて、書いた奴だけわかってればよくね?(ぉ
「プログラマにできることを制限しない」のですよ。
最近はこうるさい人が増えてきたせいで型チェックとかもするようになりましたが
基本的に、好き勝手にメッセージ投げられます、いぇい。
シロートの為にガチガチに固まったJavaとは違うんだぜぃ。
インスタンスメソッドの実行中の動的追加とか、他の言語では在り得ないキモさです。感動。
クラスとインスタンス †
オブジェクト指向言語なので、クラスの概念があります。
ただし、SmallTalk流なので他に慣れてると違和感あるかも。
僕はC++からこっちに移ったのですが、楽過ぎて死ぬ。
細かいクラスの記述方法とかは、面倒くさいのでXCodeの支援を受けてください。
どうせ一から書くことはまずないです。
ミソは、1つのクラスはxxx.hとxxx.mの2ファイルから構成されている辺り。
xxx.hは、C言語と同じくヘッダファイル(header file)
xxx.mは、Objective-Cソースファイル。(mはmethodのmらしい)
xxx.hの方にインスタンス変数についてとか公開するメソッドとか書いて
xxx.mの方にメソッドとか実際の処理内容を書いていきます。
メッセージ式 †
Objective-Cのメソッドの呼び出しは
[object method];
とやります。
引数、返り値付きだと
val = [object methodWithFirstArg:arg1 secondArg:arg2];
さらに、返り値を引数にさらに多重メッセージも出来ます。
lowerName = [[object name] lowerString];
ただし、もちろん。
C言語の関数呼び出しも日常的に使います。
int r = random();
標準ライブラリ辺りで済むようなのなら、そっちの方が速いしね。
オブジェクトの作り方 †
インスタンスの生成はクラスに対してallocを呼びインスタンスを作らせ
それに続いて返ってきたのに対してinitを呼んで初期化することで行います。
id obj = [[NSObject alloc] init];
他にも
id obj = [NSString stringWithInteger:1];
なんてのもあります。
メモリ管理は古くからのretain-release法と、ガーベジコレクションの2つの方法があります。
が、ガーベジコレクション挙動が怪しいので、ここでは却下。
- retain-release法
- 全てのオブジェクトはRetainCount(ライフ)を持ってる
- allocされると、1になる。
- retainされると、+1される。
- releaseされると、-1される。
- autoreleaseされると、そのうちに-1される。
- 0になったオブジェクトは、破棄される。
これはNSAutorelasePoolとかいうクラスが裏でこそこそとなんかやってます。
まー、使ってりゃそのうち慣れるよ。
new-deleteよりかは楽。
他との共存とか †
他との共存の為にいくつか面白いコト。
- 文字列
NSString *str = @"もじもじ";
という風に@を"の前に付けます。
すると、Objective-Cの、NSStringオブジェクトになります。
(実際はCFStringだったりするんだけど、それは気にしない。)
ってことは当然に
char *str = "Cの文字";
だとC言語のcharの配列になります。
- ポインタと配列
インスタンスオブジェクトへの参照はポインタとして扱うので
NSString *str[10];
str[0] = @"Zero";
...
などというようにインスタンスオブジェクトの配列が作れます。
作ってどうするのか、なんて聞いちゃダメです。
普通は
NSArray *array = [NSArray arrayWithObjects: @"Zero", @"One", @"Two", nil ];
とかで配列クラスを使います。
- NS
色々あって接頭詞に「NS」が付いてます。
由来はNeXTStepと聞きます。
理由ってのは、クラスに名前空間がなかったりとか色々。
- C++
当然に共存できます。Objective-C++。
C++のライブラリを使いたいと気とかによくやります。
まとめ †
以上、だらだらと書きました。
興味がある人は本とか読んでみるといいと思うよ。
オススメは荻原本。
次回は、・・・なにする?
いい加減に初心者向けを?