Objective-C Runtime 解读 (一)

Objective-C Runtime 解读 (一)

本文主要基本解读关于Runtime相关的知识, 主要针对Runtime源码, OC中的类和对象进行基本的解释, 这个也是基于本人对Runtime源码分析和看了官方文档后的一点体会.

Runtime是什么?

下面是官方文档给出的解释:

The Objective-C language defers as many decisions as it can from compile time and link time to runtime. Whenever possible, it does things dynamically. This means that the language requires not just a compiler, but also a runtime system to execute the compiled code. The runtime system acts as a kind of operating system for the Objective-C language; it’s what makes the language work.

大致的意思就是: OC是一门动态的语言, 将编译和链接的时间推迟到了运行时, 这也说明OC提供了运行时的系统, 让我们在运行时做更多的事情, 因此, 运行时系统对OC是非常重要的, 可以说, runtime让OC能够更好地运行.

简单的说, 这也跟OC语言本省的特点有关, 因为OC是一门动态语言, 需要一个运行时库来支持OC的动态性, 因此, 理解runtime机制能够有助于我们对OC的理解和学习.

Runtime术语

这里简单提一下Runtime Versions and Platforms, 主要就是Legacy and Modern Versions, 针对这两个版本, 官网给出了具体的说明:

The most notable new feature is that instance variables in the modern runtime are “non-fragile”:

In the legacy runtime, if you change the layout of instance variables in a class, you must recompile classes that inherit from it.

In the modern runtime, if you change the layout of instance variables in a class, you do not have to recompile classes that inherit from it.

现在, 我们使用的都是modern runtime, 这个是跟随Objective - 2.0一起到来的, 现在的iPhone设备和64位的OS X系统都是使用的这个版本.

Runtime中的objc_class

在OC中我们最不陌生的就是NSObject了, 下面是NSObject的定义

@interface NSObject <NSObject> {
    Class isa  OBJC_ISA_AVAILABILITY;
}

看到这里我们就可以知道, 其实NSObject中最重要的信息也就是这个isa了,下面是runtime中给出的Class的定义:

struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    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;
    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
    struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */

这里我们再次看到了isa, 其实OC语言的动态性跟这个isa是分不开的, 下面对objc_class中比较关键的字段进行介绍:

1.isa:简单点说, isa指针也就是存储了该类的类型信息, 关于isa的具体指向, 下面这张图可以很好地解释:

这里写图片描述

这里需要特别注意的就是meta - class的概念, 在Objective-C中,所有的类自身也是一个对象,这个对象的Class里面也有一个isa指针,它指向metaClass(元类), 简单点说, meta-class是一个类对象的类。

当我们向一个对象发送消息时,runtime会在这个对象所属的这个类的方法列表中查找方法;而向一个类发送消息时,会在这个类的meta-class的方法列表中查找。

meta-class之所以重要,是因为它存储着一个类的所有类方法。每个类都会有一个单独的meta-class,因为每个类的类方法基本不可能完全相同。

这就是像我们平常使用的”-” 和 “+”号方法一样, 其实二者的存储和查找方式是不太一样, 个人觉得, meta - class可能就是用来解决类方法的调用解析的.

2.cache: 第二个需要特别注意的就是这个擦cache, 我们都知道, OC采用的是动态的消息派发, 也就是运行时会有大量的消息发送和解析, 这样来说, 其实会很大程度上降低执行的效率, 那么cache其实就很好的弥补了这一点.

当我们像某个对象发送消息时, 一个接收者对象接收到一个消息时,它会根据isa指针去查找能够响应这个消息的对象。在实际使用中,这个对象只有一部分方法是常用的,很多方法其实很少用或者根本用不上。这种情况下,如果每次消息来时,我们都是methodLists中遍历一遍,性能势必很差。这时,cache就派上用场了。在我们每次调用过一个方法后,这个方法就会被缓存到cache列表中,下次调用的时候runtime就会优先去cache中查找,如果cache没有,才去methodLists中查找方法。这样,对于那些经常用到的方法的调用,但提高了调用的效率。

个人感觉, cache的设计也是objc_class这个结构体的一个闪光点.

3.superClass: 指向该类的父类,如果该类已经是最顶层的根类(如NSObject或NSProxy),则super_class为NULL。这也是实现动态消息解析的基础.

类与对象操作函数

下面简单介绍几个实用的操作函数:

1.类名

// 获取类的类名

const char * class_getName ( Class cls );

2.父类(super_class)和元类(meta-class)

// 获取类的父类

Class class_getSuperclass ( Class cls );



// 判断给定的Class是否是一个元类

BOOL class_isMetaClass ( Class cls );

3.成员变量(ivars)及属性

// 获取类中指定名称实例成员变量的信息

Ivar class_getInstanceVariable ( Class cls, const char *name );

// 获取类成员变量的信息

Ivar class_getClassVariable ( Class cls, const char *name );



// 添加成员变量

BOOL class_addIvar ( Class cls, const char *name, size_t size, uint8_t alignment, const char *types );



// 获取整个成员变量列表

Ivar * class_copyIvarList ( Class cls, unsigned int *outCount );

4.方法(methodLists)

// 添加方法

BOOL class_addMethod ( Class cls, SEL name, IMP imp, const char *types );



// 获取实例方法

Method class_getInstanceMethod ( Class cls, SEL name );



// 获取类方法

Method class_getClassMethod ( Class cls, SEL name );



// 获取所有方法的数组

Method * class_copyMethodList ( Class cls, unsigned int *outCount );



// 替代方法的实现

IMP class_replaceMethod ( Class cls, SEL name, IMP imp, const char *types );



// 返回方法的具体实现

IMP class_getMethodImplementation ( Class cls, SEL name );

IMP class_getMethodImplementation_stret ( Class cls, SEL name );



// 类实例是否响应指定的selector

BOOL class_respondsToSelector ( Class cls, SEL sel );

还有一些具体的函数, 大家可以查看源代码.

小结

本文主要介绍了runtime运行时中的一些数据结构, 包括一些基本的操作函数, 希望对理解runtime机制有所帮助.

参考
Objective-C Runtime Programming Guide
Objective-C Runtime 运行时之一:类与对象
理解 Objective-C Runtime

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值