前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

runtime

作者头像
sweet说好的幸福
发布2020-12-23 10:01:05
6320
发布2020-12-23 10:01:05
举报
文章被收录于专栏:sweet_iOSsweet_iOS

作为iOS开发者,runtime特性是必须了解的重点加分项。这并不是说你可以说出消息机制,运行时消息重定向,或者利用runtime特性实现交换方法等,而是更应该深入了解其原理,"知其然且知其所以然"才能不断成长。 Object-C是面相运行时的语言(runtime oriented language),它将编译和链接时要执行的逻辑延迟到运行时来处理。相对静态语言,我们的代码更具灵活性,在苹果封闭链中这个特性也能帮助我们进行线上修复,例如业界鼎鼎大名的JSPatch(虽然现在苹果为了安全性,一封邮件“封杀”JSPatch)。那本篇文章先从runtime功能入手,让你体会runtime的强大,再介绍其原理。在此之前,先了解下基础知识。

传送门

Objective-C Runtime 是什么?

Object-C的runtime是一个运行时库(官方传送门:https://opensource.apple.com/tarballs/objc4/),是一套纯C(C和汇编)API,感兴趣的可以下载官方源码。Objective-C runtime 创建了所有需要的结构体,让 Objective-C 的面相对象编程变为可能。

术语

1、Objective-C runtime包括两个版本,Modern Runtime和 Legacy Runtime:

  • Modern Runtime(现代的Runtime):64 位的 Mac OS X 应用和所有 iPhone OS 的应用
  • Legacy Runtime: 所有 32 位的 Mac OS X 应用

2、Method 有 2 种基本类型的方法:

  • Instance Method(实例方法):以 ‘-’ 开始,比如 -(void)doFoo; 在对象实例上操作
  • Class Method(类方法):以 ‘+’ 开始,比如 +(id)alloc。方法(Methods)和 C 的函数很像,是一组代码,执行一个小的任务。如- (NSString *)movieTitle

3、Selector Selector 在 Objective-C 中 selector 只是一个 C 的数据结构,用于表示一个你想在一个对象上执行的 Objective-C 方法。

4、Meta Classes 类类型

基础重点

代码语言:javascript
复制
typedef struct objc_class *Class;  
typedef struct objc_object {  
    Class isa;  
} *id;  

这段代码 5、objc_class Objective-C 中 NSObject是大多数类的根类。

代码语言:javascript
复制
@interface NSObject <NSObject> {  
    Class isa  OBJC_ISA_AVAILABILITY;  
}  

从中可以看出NSObject有一个isa属性,类型是Class。Class 是一个 objc_class 结构类型的指针

代码语言:javascript
复制
struct objc_class {  
     struct objc_class *isa;  
  
     struct objc_class *super_class;   
     const char *name;    
     long version;  
     long info;  
     long instance_size;  
     struct objc_ivar_list *ivars;  
     struct objc_method_list **methodLists;  
     struct objc_cache *cache;  
     struct objc_protocol_list *protocols;  
};  

可以看到Objective-C对象系统的基石:struct objc_class结构如下:

  • isa指针:指向该对象所属类型的类型对象(Class Object)。在Objective-C中,类也是用对象来表示的,而类的isa指针指向它的metaclass(存储静态成员变量和类方法)。
  • super_class指针:指向父类。
  • name:类名称。
  • version:类的版本信息。
  • info:运行期使用的标志位,比如0x1(CLS_CLASS)表示该类为普通class,0x2(CLS_META)表示该类为 metaclass。
  • instance_size:实例大小,即内存所占空间。
  • ivars:指向成员变量列表的指针。
  • methodLists:根据标志位的不同可能指向不同,比如可能指向实例方法列表,或者指向类方法列表。
  • cache:因为Objective-C的消息转发需要查找dispatch table甚至可能需要遍历继承体系,所以缓存最近使用的方法。
  • protocols:类需要遵守的协议。

6、objc_object objc_object 只有一个指向类的 isa 指针,就是我们说的术语 “isa pointer”(isa 指针)。

7、isa 指针 isa 指针是当你向对象发送消息时,Objective-C Runtime 检查一个对象并且查看它的类是什么然后开始查看它是否响应这些 selectors 所需要的一切。

8、id指针 id数据类型是一个指向struct objc_object结构的指针,这个指针包含一个纸箱objc_class结构的isa 指针。 更确切地说,id是指向Class类型的指针,而Class又是指向struct objc_class结构的指针。

9、 Class Cache 就是class_object定义中的struct objc_cache *cache; 当 Objective-C runtime 沿着一个对象的 isa 指针检查时,它会发现一个对象实现了许多的方法。然而你可能只调用其中一小部分的方法,也没有意义每次检查时搜索这个类的分发表(dispatch table)中的所有 selector。所以这个类实现了一个缓存,当你搜索一个类的分发表,并找到合适的 selector 后,就会把它放进缓存中。所以当 objc_msgSend() 在一个类中查找 selector 时会先查找类缓存。有个理论是,当你在一个类上调用了一个消息,你很可能之后还会调用它。

runtime 常用开发应用场景

http://www.jianshu.com/p/19f280afcb24,“白开水”的这篇文章介绍的很好,标题“面试、工作”就赢了

  • runtime 消息机制 消息机制原理:对象根据方法编号SEL去映射表查找对应的方法实现。 我们写 OC 代码,它在运行的时候也是转换成了 runtime 方式运行的。任何方法调用本质:就是发送一个消息(用 runtime发送消息,OC 底层实现通过 runtime 实现),每一个 OC 的方法,底层必然有一个与之对应的 runtime 方法。 OC的函数调用成为消息发送,属于 动态调用过程。在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。

作用

利用runtime 可以做一些OC不容易实现的功能:

  • 动态交换两个方法的实现(特别是交换系统自带的方法)
  • 动态添加对象的成员变量和成员方法
  • 获得某个类的所有成员方法、所有成员变量

面试题 1、method swizzling?

2、objc中向一个对象发送消息[obj foo]和objc_msgSend()函数之间有什么关系? objc_msgSend()是[obj foo]的具体实现。 在runtime中,objc_msgSend()是一个c函数,[obj foo]会被翻译成这样的形式objc_msgSend(obj, foo)。 1、去obj的对应的类中找方法 2、先找缓存,找不到再去找方法列表, 3、再找父类,如此向上传递。 4、最后再找不到就要转发。

3、什么时候会报 Unrecognized selector 的异常? 当调用对象的某个方法的时候, 如果在当前类中没有找到此方法, 那么就到当前类的父类中去寻找, 如果在父类中没有找到, 那么就去父类的父类中去寻找, 一直找到 NSObject 都没有这个方法, 就会报 Unrecognized selector 的异常.

4、runtime如何通过selector找到对应的IMP地址?(分别考虑类方法和实例方法) IMP寻址 http://blog.csdn.net/dp948080952/article/details/52437451

5、_objc_msgForward函数是做什么的,直接调用它将会发生什么? http://www.jianshu.com/p/04ba5f3bfc2b

6、消息机制方法调用流程 方法:实例方法,类方法 http://www.jianshu.com/p/d5ca2cdd4fa7 对官方文档的翻译,略显粗糙,适用于我这种英文比较烂的童鞋?

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 传送门
  • Objective-C Runtime 是什么?
  • 术语
  • 基础重点
  • runtime 常用开发应用场景
  • 作用
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档