objc runtime 源码解析
2016-06-12 本文已影响477人
sakuragi
类和对象是如何定义的
-
类
An opaque type that represents an Objective-C class.
typedef struct objc_class *Class
可以看出,在OC中,类其实是一个
objc_class
的结构体指针
struct objc_class:objc_object {
Class superclass;//父类
const char *name;//类名
uint32_t version //版本号,默认为0
uint32_t info;//信息
uint32_t instance_size;//实例大小
struct old_ivar_list *ivars;//成员变量列表
struct old_method_list methodLists //方法列表(这里为什么要两个)?
Cache cache;//方法缓存
struct old_protocol_list *protocols //协议列表
...
}
我们再看看```objc_object```的定义
struct objc_object {
private:
isa_t isa;
public:
Class ISA();
Class getIsa();
}
在OC中,所有的类本身也是一个对象,这个对象的Class里面也有一个isa指针,它指向*metaClass*。
- 对象
> Represents to an instance of a class
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
}
#id
>A pointer to an instance of a class
typedef struct objc_object *id;
是一个objc_object类型的结构体指针
在OC中,我们经常声明一个```id obj```的对象,这里转换一下其实是这样一行代码``` struct objc_object *obj```。可以看出 obj被声明为的一个结构体指针。obj指针指向的类型是一个结构体objc_object。objc_object结构体中有一个 isa指针,isa指针指向一个objc_class的类型。
#SEL
>An opaque type that represents a method selector.
type struct objc_selecotr *SEL;
在runtime的源码中,我们没有找到```objc_selector```的定义
首先我们必修明确一点,SEL的拥有者是我们的method,一个method的selector用于表示运行时这个method的实现,我们可以通过一段代码来看看一个
- (void) method {}
SEL sel = @selector(method);
NSLog(@"sel = %p",sel);
>sel : 0x100014ffa
在编译期,系统会根据方法名,参数列表生成一个唯一的标识,这个标识是int型的SEL.
因此,在同一个类中,或者是他的继承体系中,只能存在一个方法名相同的方法,就算参数类型不同都不行,而在C++或者java中,允许方法名相同而参数类型不一样的方法同时存在。
#IMP
>A pointer to the function of a method implementation
typedef id (*IMP)(id,SEL, ...);
[函数指针百度百科的定义](http://baike.baidu.com/link?url=nxL0nYcQ4dRDkhbYBo_sGVOzWSlW3_jOP-eMmLNVVwPr_GWT7pW711bU7u_KcK-aAHR_nQ8gpssHCkF9kfTtAK)
可以看出,IMP是一个函数指针,第一个参数id是指向self的指针,如果是类实例方法,那么指向实例的地址,如果是类方法,则指向元类的地址。第二个参数是选择器selector,后面的是参数列表。