Objective-C Runtime 初探(一)
Objective-C 是一种通用、面向对象的编程语言。它以 C 语言为基础并添加了 Smaltalk 的消息特性。它是一种具有动态特性,强类型的编译型语言,其中动态特性是指可以在运行时创建类,为类添加成员变量,为类添加方法。我认为 Objective-C 语言设计的比较灵巧:只在 C 语言的基础上增加了比较薄的一层,就具有了面向对象特性和一定的动态特性,于是非常好奇它是如何实现这些特性的。
源码版本:objc4-437.3,可以从苹果的网站上下载。
Objective-C Runtime 2.0 与之前的相比进行了重新实现,这里不分析 2.0 的运行时。
Class 的定义
typedef struct objc_class *Class; struct objc_class { Class isa; #if !__OBJC2__ Class super_class; const char *name; long version; long info; long instance_size; struct objc_ivar_list *ivars; struct objc_method_list **methodLists; struct objc_cache *cache; struct objc_protocol_list *protocols; #endif } OBJC2_UNAVAILABLE; |
id 的定义
typedef struct objc_object { Class isa; } *id; |
SEL 的定义
typedef struct objc_selector *SEL; |
在源码中没有直接找到 objc_selector 的定义,从一些书籍上与 Blog 上看到可以将 SEL 理解为一个 char* 指针,经过自己测试是正确的。但是可以猜测到 struct objc_selector 的定义为:
struct objc_selector { char name[64 or ...]; ... }; |
只要遵循如上原型,就可以将 SEL 理解为一个 char*。大家可能考虑 name 会不会是在Heap上呢?基于如下三个理由,我认为不会在Heap上:第一、name 在编译时就确定了,在加载编译链接后文件时直接放到静态存储区就可以了;第二、通过用 IDA 反汇编Mach-O 文件,可以以字符串的形式看到所有方法;第三、虽然现在编译器支持很长的方法名,但基本都有一个固定长度(参考C99标准)。
IMP 的定义
typedef id (*IMP)(id, SEL, ...); |
IMP 是一个函数指针,而且从原型上可以看出跟用 C 语言模仿面向对象特性很像,比如:C++,Python 等,第一参数都是 self。