2.Runtime

Runtime在iOS开发中作为内部核心之一,需要花更多时间去理解。

 

1.Runtime

 

Runtime又叫运行时,是一套底层的C语言API,无论是oc还是swift,底层都是基于这个来实现的,比如发送消息:

[receiver message]

底层运行时会被编译器转化为:objc_msgSend(receiver, selector)

如果还添加其他参数:[receiver message:(id)arg...]

底层运行时会被编译器转化为:objc_msgSend(receiver, selector, arg1, arg2, ...)

 有很多的类和成员变量在我们编译的时候是不知道的也是无法确定的,而在运行时,我们所编写的代码会转换成完整的确定的代码运行,因此,只有编译器是不够的,我们还需要一个运行时系统来处理编译后的代码。也是因为这样,runtime给oc语言带来了动态语言的特性,也为c语言带来了面向对象的特性。

 

2.Runtime交互

 

2.1   编译器将OC代码转换成运行时代码,运行时确定数据结构和函数。

2.2  一般情况下,NSObject类仅定义了完成某件事情的模板,并没有提供所需要的代码。例如.description方法,该方法返回了类内容的字符串表示,NSObject类并不知道子类的内容,所以只返回类的名字和对象地址。

一些NSObject的方法可以从Runtime系统中获取信息,允许对象进行自我检查。例如:

    -class方法返回对象的类;
    -isKindOfClass: 和 -isMemberOfClass: 方法检查对象是否存在于指定的类的继承体系中(是否是其子类或者父类或者当前类的成员变量);
    -respondsToSelector: 检查对象能否响应指定的消息;
    -conformsToProtocol:检查对象是否实现了指定协议类的方法;
    -methodForSelector: 返回指定方法实现的地址。
2.3  Runtime系统是具有公共接口的动态分享库。
 
 
3.Runtime相关术语
 
3.1 SEL(OC)/Selector(swift)
selector是方法选择器,相同的类中不会有两个命名相同的两个方法。selector对方法名进行包装,以便找到对应的实现方法。数据结构如下:
typedef struct objc_selector *SEL;
 
3.2 id
id是一个参数类型,他是指向某个类的实例的指针。它的数据结构如下:
typedef struct objc_object *id;
struct objc_object{ Class isa; };
objc_object结构体包含了一个isa指针,根据isa指针就可以找到对象所属的类。
 
3.3 Class
Class其实是指向objc_class结构体的指针。数据结构如下:
typedef struct objc_class *Class;
struct objc_class {
    Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
 
#endif
}OBJV2_UNAVAILABLE;
 
4.Runtime与消息的关系
 
消息直到运行时才会与方法实现进行绑定。消息发送的步骤:
  • 首先检测这个selector是不是要忽略。比如有了垃圾回收就不理会release这些函数。
  • 检测这个selector的target是不是nil,Objc允许我们对一个nil对象执行任何方法不会Crash,因为运行时会被忽略掉。
  • 如果上面两步骤都通过了,那么就会开始查找这个类的实现IMP,先从cache里查找,如果找到了就运行对应的函数去执行相应的代码。
  • 如果cache找不到就找类的方法列表中是否有对应的反法。
  • 如果类的方法列表中找不到就到父类的方法列表中查找,一直找到NSObject类为止。

 

posted @ 2019-12-04 17:36  灰熊Grizzly  阅读(172)  评论(0编辑  收藏  举报