关于iOS的runtime

runtime是一个颇有意思的东西,若是你学iOS开发很常常就会用到或被问到runtime。那么runtime是什么呢,如何去了解它。ios

runtime:中文名 运行时,系统在编译时留下的一些 类型,操做在运行的时候动态去分析,处理,这也说明了object-c是一个动态语言。(swift与之不一样,swift虽然能够经过调用oc的runtime,可是swift自己是静态语言。可是却经过可以和oc交互变成了具备动态特性的静态语言,这是闲话,不扯了)。c++

要了解runtime,知道runtime是什么。我以为最关键的是看 objc/objc.h,objc/runtime.h文件。swift

首先要知道object-c底层是用c,c++写的数组

A. objc.h:缓存

一、objc.h文件里面定义了一个id 是一个objc_object结构体指针类型,结构体中又一个isa这样的成员,isa是一个Class类型。而Class是 objc_class * 类型app

也就是说一个 oc中的object其实就是一个带有objc_class*成员,并由这个objc_class*类型的成员来解释这个object是什么东西,包括这个object是什么类型,有什么方法。方法参数组成,有什么协议,类别等。学习

typedef struct objc_class *Class;spa

 

struct objc_object {指针

    Class isa  OBJC_ISA_AVAILABILITY;对象

};

 

二、而后咱们来看 Class这个类型,Class这个类型是objc_class*的别名。具体意思不就是说是用objc_class这个结构体对应的指针类型。

三、接着是SEL, 跟Class差很少这个也是另一个结构体指针的别名,这个对应的结构体叫作objc_selector.

其中objc_object能够在runtime中看到具体的结构。objc_selector我没找到在哪里,谁看到了提醒一下哦。

四、而后是方法实现的定义:

/// A pointer to the function of a method implementation. 

#if !OBJC_OLD_DISPATCH_PROTOTYPES

typedef void (*IMP)(void /* id, SEL, ... */ ); 

#else

typedef id (*IMP)(id, SEL, ...); 

#endif

接着下面是定义了一些对方法名,变量的一些操做。

B.runtime.h

runtime.h文件中定义了不少的结构体和方法。

一、首先是给几个结构体指针类型定义了几个别名 objc_method * 对应Method, objc_ivar *对应Ivar,objc_catagory *对应 Catagory objc_property *对应objc_property_t 类型。

二、objc_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;

从上面这个结构中能够看到一个objc_class中有一个 Class 定义的isa成员,这个成员其实在A中能够看出来 其实也是一个objc_class *这种类型。(这种定义方式在咱们学习c++的时候有学过。谭浩强的《面向对象c++》..)

而后咱们这时要知道object-c里面的类和实例其实都是一个定义的对象,并且对应的指针是isa .也就是说系统 像malloc这个操做后会把 指针存到这个 isa中。

这样其实object-c里面的类和对象其实都是经过结构体指针来实现的。

而后咱们再看 objc_class中的结构其中包括了 父类,类名,版本, 示例大小,实例中包含的变量列表,方法列表,缓存,协议列表。这些东西

在往下看 能够看到Protocol是一个objc_object类型,而后经过objc_object里面的isa 指针保存对应的名字,方法,变量等。因此经过这个你能够认识到定义一个协议是能够往里面加你要的属性的。

而后往下

objc_method_description的结构体这个东西定义了方法有方法名和方法类型

objc_property_attribute_t这个结构体定义了属性的特色包括须要有 名称 和 值。

 

再往下看有不少对实例在运行时的操做,这里我就省略了。又一个方法叫

imp_implementationWithBlock

从这里能够拿到一个block的对应的实现的指针。(block是一个对象)

再往下有给object设置关联的方法,这些操做就是平时用到的在类别中如何给一个类添加一些属性(类别中是不能添加属性的,不过经过这个方法能够为你定义的属性的set,和get方法至关于重写的操做。而后实现了一个类别的属性)

objc_setAssociatedObject

 

objc_getAssociatedObject

 

objc_removeAssociatedObjects

再往下走又是一堆结构体 protocol_list, objc_catagory, objc_ivar, objc_ivar_list, objc_method, objc_method_list, objc_cache, objc_module.

这些结构体分别对应的定义了咱们在oc中常常用到的 类别,方法等东西的结构(含糊的讲一下,有点多)

总结一下,也就是说其实ios的runtime是经过不少个 struct类型来缓存对应的结构并在运行的时候经过这些结构特征和对应的指针来分析并进行对应的操做。

因此多看里面的结构组成就对了。

 

以上属于我的理解

推荐一篇讲的蛮详细的(http://chun.tips/blog/2014/11/06/bao-gen-wen-di-objective[nil]c-runtime(3)[nil]-xiao-xi-he-category/) 

若是想更深刻了解具体内部实现原理,就要看opensource.apple.com里面的内容了,如: https://opensource.apple.com//source/objc4/objc4-706/runtime/

相关文章
相关标签/搜索