iOS Runtime理解

 runtime

概述: runtime又叫运行时,是一套底层C语言API,是iOS系统的核心之一。开发者在编码过程中,可以给任意一个对象发送消息,在编译阶段只是确定了要向接受着发送这条消息,而接受者如何响应和处理这条消息,就要看运行时来决定了

 C语言中,在编译器就确定要调用哪个函数,而OC的函数,属于动态调用过程,在编译器并不能真正决定调用哪个函数,只有在真正的运行时才会根据函数的名称找到对应的函数来调用。OC是一个动态语言,这意味着它不仅要一个编译器,也需要一个运行时系统来动态创建类和对象、进行消息传递和发送

1.消息转发

Runtime的特性主要是消息传递,如果消息在对象中找不到,就进行转发。Objective-C是一个动态语言,这意味着它不仅需要一个编译器,也需要一个运行时系统来动态创建类和对象、进行消息传递和转发。Runtime的核心是消息传递。

(1)消息传递的过程

一个对象的方法[obj test],编译器转成消息发送objc_msgSend(obj,test),Runtime执行的流程是这样的

a.首先通过obj的isa指针找到它的class

b.在class的method list找test

c.如果class中没找到test,继续往它的superclass中找

d.一旦找到test这个函数,就去执行它的IMP

由于效率问题,每个消息都遍历一次objc_method_list并不合理,所以需要把经常被调用的函数缓存下来,去提高函数查询的效率。这也就是objc_class中另一个重要的成员objc_cache做的事情。找到test之后,将test的method_name作为key,method_imp作为value。当再次收到test消息的时候,可以直接在cache里找。

类对象(objc_class)

Objective-C类是由Class类型来表示的,它实际上是一个指向objc_class结构体的指针。struct objc_class结构体里面定义了很多变量。结构体里保存了指向父类的指针、类的名字(name)、版本、实例变量列表(ivars)、方法列表(methodLists)、缓存(cache)、遵守的协议列表(protocols),由此可见,类对象就是一个结构体struct objc_class,这个结构体存放的数据就是元数据

理解Runtime就是理解iOS在运行时他的数据存储以及他的类、实例、类对象、元类她们之间的关系和作用。

(2)消息转发机制

归根到底,Objective-C中所有的方法调用本质就是向对象发送消息

1.类中创建方法-(void)test

2.iOS系统为这个方法创建一个编号,SEL(test)并添加到方法列表里面

3.当调用这个方法的时候系统去方法列表里查找这个方法,找到了就执行

所以,调用一个方法就会进行一次发送消息也就是在这个类的方法列表里找,如果在该类中找不到就到该类的父类里找,如果父类还找不到就一直搜索到继承树的根部,如果找不到或者消息转发不成功那就会报unrecognized selector错。

1.动态方法解析

Objective-C运行时会调用+resolveInstanceMethod:或者 +resolveClassMethod:让你有机会提供一个函数实现,如果你添加了函数并且返回YES,那么运行时就会重新启动一次消息发送的过程。如下图:

虽然没有foo:的实现函数,但是通过class_addMethod()动态添加了fooMethod函数,并执行了这个函数并且打印成功。如果reslove返回NO运行时就会移到下一步:forwardingTargetSelector

2.直接消息转发

如果目标对象实现了forwardingTargetSelector,Runtime这时就会调用这个方法,给你把这个消息转发给其他对象的机会


从图中可以看出我们通过forwardingTargetForSelector方法将当前类的方法转给Father类实现了,打印成功。

3.完整消息转发

如果在上一步还不能处理未知消息,那唯一能做的就是启动消息转发机制。首先它会发送methodSignatureForSelector消息获得函数的参数和返回值类型。如果methodSignatureForSelector返回nil,Runtime则会发出doesNotRecognizeSelector。如果返回一个签名函数,Runtime就会创建一个NSInvocation对象并发送forwardInvocation消息给目标对象。


Runtime的实际应用

1.使用Runtime交换方法


2.动态添加方法(目前不是很懂)

3.给分类添加属性


4.消息转发(热更新)解决Bug(JSPatch)

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

推荐阅读更多精彩内容