iOS中的类和对象

iOS中的类和对象

1.runtime里面声明了id和Class,简化得到以下

struct objc_class {
struct objc_class *isa;
}
struct objc_object {
struct objc_class *isa;
}
typedef struct objc_class *Class;//类(class object)
typedef struct objc_object *id;//对象(instance of class)

可以看到iOS中id代表了一个对象,凡是首地址是*isa的指针,都可以看成对象,像前一篇文章的说的

Block原理解析。可以通过查看isa指针,查找到对象所属的类别

我们看看objc_class是什么东西。通过查看源码,可以得到

struct objc_class {
Class isa  OBJC_ISA_AVAILABILITY;
Class super_class                                        OBJC2_UNAVAILABLE;//父类
const char *name                                         OBJC2_UNAVAILABLE;//类名
long version                                             OBJC2_UNAVAILABLE;
long info                                                OBJC2_UNAVAILABLE;
long instance_size                                       OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;//ivar列表(ivar:对象的实例变量,包括类型和名字)
struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;//方法列表
struct objc_cache *cache                                 OBJC2_UNAVAILABLE;//方法缓存列表
struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;//协议列表
} OBJC2_UNAVAILABLE;

我将里面的重点几个struct拉出来讲讲

1.objc_ivar_list //ivar的列表,一个ivar定义对象的实例变量,包括类型和名字
struct objc_ivar {
char *ivar_name                                          OBJC2_UNAVAILABLE;
char *ivar_type                                          OBJC2_UNAVAILABLE;
int ivar_offset                                          OBJC2_UNAVAILABLE;
int space                                                OBJC2_UNAVAILABLE;
}                                                            OBJC2_UNAVAILABLE;
struct objc_ivar_list {
int ivar_count                                           OBJC2_UNAVAILABLE;
int space                                                OBJC2_UNAVAILABLE;
/* variable length structure */
struct objc_ivar ivar_list[1]                            OBJC2_UNAVAILABLE;
}  
2.objc_method_list //方法列表,objc_method_list 存储了objc_method,一个objc_method包含了SEL(可以理解成方法名的映射)和IMP(方法名SEL对应的实现)
struct objc_method {
SEL method_name                                          OBJC2_UNAVAILABLE;
char *method_types                                       OBJC2_UNAVAILABLE;
IMP method_imp                                           OBJC2_UNAVAILABLE;
}                                                            OBJC2_UNAVAILABLE;
struct objc_method_list {
struct objc_method_list *obsolete                        OBJC2_UNAVAILABLE;
int method_count                                         OBJC2_UNAVAILABLE;
int space                                                OBJC2_UNAVAILABLE;
/* variable length structure */
struct objc_method method_list[1]                        OBJC2_UNAVAILABLE;
}  
3.objc_cache:方法的集合,用于优化消息派发流程(下一篇文章会详细讲解),而Method和objc_method指的是同一个struct,只是通过typedef进行了重命名
struct objc_cache {
unsigned int mask /* total = mask + 1 */                 OBJC2_UNAVAILABLE;
unsigned int occupied                                    OBJC2_UNAVAILABLE;
Method buckets[1]                                        OBJC2_UNAVAILABLE;
};

所有对象的实例变量的isa都指向Class,而Class的isa指针都指向meta-Class。

方法调用:

如有一个Person类,它的实例变量jimmy的isa指针指向Person(Class),而Person(Class)的isa指针指向Person(meta-Class)。

Person(Class)是一个全局变量,其中记录了类名,成员变量信息,property信息,protocol信息,实例方法列表等。

Person(meta-Class)是一个全局变量,其中记录了类名,类方法列表等。

Person *jimmy = [Person new];
[jimmy drink];

我们向jimmy(instance) 发送drink消息,运行时会通过isa指针查找到Person(Class),这里保存着本类中定义的实例方法的指针。

[Person drink2];

我们向Person(Class)发送drink2消息,运行时会通过isa指针查找到Person(meta-Class),这里保存着本类中定义的类方法的指针。

继承体系中isa和superClass指针的走向:

objc_class中除了isa指针外,还有个super_class指针,明显super_class指的是父类。而如果有NyanCat:Cat:NSObject 这样一个继承树,画出图来就是这样。

iOS中的类和对象_第1张图片

如图所示,跟随黑线,可以看到isa的指向。运行时,每个对象的isa都不为空,这样只要是一个id类型对象,runtime都可以通过访问首地址偏移(isa)来获取该对象的信息。

上图中跟随绿线,可以看到superclass的指向。当运行时在搜寻方法、ivar信息时,如果没有找到信息,则会沿superclass的线查找上去,最终NSObject(根类)的superclass是nil。

如果自己定义了一个根类(比如NSProxy),则这个根类会替换图中NSObject的位置。

你可能感兴趣的:(iOS中的类和对象)