关于Runtime,我有话要说


图是网上找的.jpg

简介

    Objective-C(下面简称OC) 是基于面向对象思想而对C 语言进行扩展的一种动态编程语言,而这个扩展的核心是Runtime。Runtime是一个用C语言和汇编语言写的动态库,它是整个OC运行框架的一块基石。

与Runtime交互

    与Runtime交互有三种方式,分别是:
  1.通过Objective-C 源代码
       
大部分情况下我们都是使用OC在XCode开发工具上进行项目开发,而不需要涉及到Runtime的使用。比如,当我们调用对象方法-(void)doSomething:(NSString *)str时,只需要在键盘上敲出"[self doSomething:@"xxx"];"即可,编译过程中系统会自动帮我们转换为"objc_msgsend(person,@selector(doSomething),@"xxx");"。
    2.通过 Foundation 框架的NSObject类定义的方法
        Cocoa中大部分类都是NSObject的子类,都继承了NSObject的行为。NSObject类中一些方法可以从Runtime系统中获取信息,如:
       -class   方法返回对象的类;
      -isKindOfClass:和-isMemberOfClass:方法检查对象是否存在于指定的类的继承体系中(是否是其子类或者父类或者当前类的成员变量);
      -respondsToSelector:检查对象能否响应指定的消息;
    3.通过对 runtime 函数的直接调用
     
Runtime 系统是一个由一系列函数和数据结构组成,具有公共接口的动态共享库。使用前需要先导入<objc/message.h>、<objc/runtime.h>。类的操作方法大部分是以class为前缀的,而对象的操作方法大部分是以objc或object为前缀。

Runtime基础数据结构

1.Class
       
Class实际上是一个指向objc_class结构体的指针,对objc_class结构体的定义如下

object_class结构体.jpg

定义中有几个重要的字段:
     1)isa:Objc中所有的类自身也是一个对象,这个对象的class也有一个isa指针,指向metaClass元类。
      2) super_class: 指向该类的父类,如果该类是顶部根类,则super_class 为NULL。
      3) cache: 用于缓存最近使用的方法,该方法可以有效提高查询指定方法的效率。
2.Meta Class(元类)
     
meta class 是一个类对象的类,当我们向一个对象发送消息时,runtime会在这个对象所属的类的方法列表中查找方法;而向一个类发送消息时,会在这个类的meta class的方法列表中查找。而meta class作为一个类,它的isa指向基类的meta class,基类的meta class的isa指针又指向它自己。

网上找的图.jpg

3.Method

class_addMethod.jpg

Method是一种代表类中的某个方法的类型。图中的函数为为类添加方法,从参数可知Method结构体有SEL字段、IMP字段、char字段。SEL类型仅代表方法名,即使相同方法名的方法在不同类中定义,但方法选择器还是相同的。types表示方法的参数类型和返回值类型。IMP是一个函数指针,指向了函数体,即函数的实现。

消息发送

      当消息发送给一个对象时,objc_msgSend通过对象的isa指针获取到类的结构体,然后在方法列表中查找方法的selector。如果没有找到selector,则通过super_class找到父类,在父类的方法列表中查找selector,以此类推。若最后没有找到selector,则会进行消息转发。

消息转发

     当以"[object message]"方式调用方法时候,若找不到selector则编译器会报错。若以“perform...”形式来调用,则需要等到运行时才能确定object是否能接收message消息。如果不能则程序崩溃。消息转发机制分为三个步骤:
    1).动态方法解析
    2).备用接收者
    3). 完整转发
  1.动态方法解析
         
对象接收到未知消息时,调用resolveInstanceMethod:。在这个方法中,我们有机会为该未知消息新增一个处理方法。

重写方法.jpg

  2.备用接收者
    若没有新增处理方法,则会调用forwardingTargetForSelector方法。如果一个对象实现了这个方法,并返回一个非nil的结果,则这个对象会作为消息的新接收者,而且消息会被分发到这个对象。

备用接收者.jpg

 3.完整消息转发
    若还是不能处理未知消息,则只能启用完整的消息转发机制。调用forwardInvocation:方法。对象会创建一个表示消息的NSInvocation 对象。把与消息有关的信息都封装到NSInvocation里面,包括selector、target和参数。在该方法中选择将消息转发给其它对象。还有一点,我们需要重写methodSignatureForSelector:方法,消息转发机制从这个方法获取的信息来创建NSInvocation对象,因为我们需要重写这个方法并为给定的selector提供一个合适的方法签名。PS:下图Viewcontroller只是一个普通的类。

完整消息转发.jpg


整个过程如下图所示:

网上找的图.jpg



Method Swizzling(方法替换)

在Objc中,运行时会自动调用每个类的两个方法。+load 会在类初始加载时调用,+initialize会在第一次调用类的类方法或实例方法之前被调用。由于方法替换会影响到类的全局状态,因此要尽量避免在并发处理中出现竞争情况。

method swizzling.jpg

要注意的是swizzling应该总在+load且dispatch_once中执行。+load能保证在类的初始化过程中被加载,并保证这种改变应用级别的行为的一致性。相比之下,+initialize在其执行时不提供这种保证。

总结

   深入理解Runtime 更有利于我们利用消息机制写出更强大的代码,菜鸟一枚,请喷轻一点~

参考博客:http://yulingtianxia.com/blog/2014/11/05/objective-c-runtime/
                  http://southpeak.github.io/categories/objectivec/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,681评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,710评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,623评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,202评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,232评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,368评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,795评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,461评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,647评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,476评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,525评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,226评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,785评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,857评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,090评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,647评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,215评论 2 341

推荐阅读更多精彩内容

  • 转至元数据结尾创建: 董潇伟,最新修改于: 十二月 23, 2016 转至元数据起始第一章:isa和Class一....
    40c0490e5268阅读 1,678评论 0 9
  • 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的转载 这篇文章完全是基于南峰子老师博客的...
    西木阅读 30,531评论 33 466
  • 参考链接: http://www.cnblogs.com/ioshe/p/5489086.html 简介 Runt...
    乐乐的简书阅读 2,127评论 0 9
  • 原文出处:南峰子的技术博客 Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了...
    _烩面_阅读 1,212评论 1 5
  • 转载:http://yulingtianxia.com/blog/2014/11/05/objective-c-r...
    F麦子阅读 724评论 0 2