Dynamic Objective-Cを読んでいて色々面白そうなことが書いてあるのでそのメモ。
##ランタイムAPI
Objective-Cの実装は、紐解けばC言語での実装になっています。
なので、ランタイムAPIを駆使すればほぼすべての処理に対してあとから干渉することが出来ます。
(例えば、コンパイル時に存在しないクラスを生成したり、とか)
ただ、ARCがオンの場合には動作しないものもあるので、なにかいじってみる場合は注意してください。
また、ランタイムAPIを利用する場合は<objc/runtime.h>
をimportする必要があります。
##クラスの実体
Objective-Cで実現されているクラス構造は、実はすべてCの構造体により実現している。
よく使われるid
型の宣言は以下のようになっている。
typedef struct objc_object {
class isa;
} *id;
ちなみにisa
は「イズーア」だと思われる。(オブジェクト指向の用語である「isa」)
つまりisa
メンバは継承元(スーパークラス メタクラス(コメントで指摘いただきました))への参照を持つ。
(余談だけど「This class is a meta class.」の「is a」から来ていると思う。(英語の文章はわりと適当;))
##クラスからインスタンスを生成
id hoge = class_createInstance([hoge class], 0);
class_createInstance
関数でインスタンスを生成する。
##インスタンスメソッドの実装を取得
Objective-Cではちょっとおもしろい実装になっていて、メソッドとメソッドの実装が切り分けられている。
上で、Objective-Cのクラスは、実はただのCの構造体と書いたけど、メソッドもただの構造体の中の1メンバに過ぎない。
そして構造体にはメソッド「名」とメソッドの「実装」をそれぞれ個別に持つようになっていて、ランタイム時に指名されたメソッドの実装を取り出して実行する、ということをやっている。
そしてその「メソッドの実装」の型がIMP
型になる。
###サンプルコード
Method method;
IMP imp;
method = class_getInstanceMethod([NSString class], @selector(length));
imp = method->method_imp;
ちなみにこれを読んで腹落ちしたのがObjective-Cの「セレクタ」という概念。
最初はなにを「セレクト」しているんだろうとずっと疑問だったけど、つまりは「メソッドの実装」をセレクトしていた、というわけ。
##ランタイムAPIのリファレンス
Objective-C Runtime Reference