LoginSignup
14
10

More than 5 years have passed since last update.

[Objective-C] ランタイムAPIのメモ

Last updated at Posted at 2014-02-09

Dynamic Objective-Cを読んでいて色々面白そうなことが書いてあるのでそのメモ。

ランタイムAPI

Objective-Cの実装は、紐解けばC言語での実装になっています。
なので、ランタイムAPIを駆使すればほぼすべての処理に対してあとから干渉することが出来ます。
(例えば、コンパイル時に存在しないクラスを生成したり、とか)

ただ、ARCがオンの場合には動作しないものもあるので、なにかいじってみる場合は注意してください。
また、ランタイムAPIを利用する場合は<objc/runtime.h>をimportする必要があります。

クラスの実体

Objective-Cで実現されているクラス構造は、実はすべてCの構造体により実現している。
よく使われるid型の宣言は以下のようになっている。

struct.m
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

記事

14
10
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
10