美文网首页
iOS Runtime修炼<二>

iOS Runtime修炼<二>

作者: 莮亾 | 来源:发表于2017-01-17 16:52 被阅读19次

基情四射的日子

我总是对神秘的事物产生兴趣,自从知道了Objective-C的Runtime技能,我便试着接近它,讨好它,因为只有对这个技能了如指掌,我才能征服它,才能在修仙的道路上顺利前进。


消息传递函数: objc_msgSend

这个可以说是Runtime系统的根基,因为所有的OC方法调用最终都会转换成objc_msgSend函数的调用。这么重要的秘密,没想到只给丫喝了两瓶啤的,它就告诉了我。看来酒量不行,难在江湖混呐。

招式破解:[receiver message] ----> objc_msgSend(receiver, selector, arg1, arg2, ...)     objc_msgSend在执行的过程中,会悄悄的传入接收对象和方法选择器这两个参数。

看了Runtime醉酒的样子,我心里嘀咕着:“就这货,怎么能有这么强大的力量?”果然不出我所料,这货有一枚神器叫编译器,一直在默默的帮助着它。就这个消息传递,也是因为编译器为每一个类和对象构建了各自的结构,才能使其顺利施放技能。那我倒是要看看,这个类结构到底是啥?

类结构破解:    

类结构包含了一个指向父类的指针(isa)和一个类调度表。类调度表记录了类中选择器对应的具体内存地址,就像这样:selector ----> address 。当调用一个方法,也就是给对象发送一个消息的时候,会根据isa找到类结构,并在调度表中查找匹配的selector;如果不能匹配,objc_msgSend就根据isa到父类类结构里与调度表中的selector匹配,依此类推直到NSObject类。一旦匹配到了selector,就调用表中记录的函数(address),否则将启动消息转发机制。这种在运行时选择方法实现的过程称为动态绑定。

强大的Runtime必然会有很多的招式,这招动态绑定,我给90分。因为我觉着这样灵活的招式,肯定会有它的弊端。首先在编译期不能确定方法的位置,这就给运行时造成了不可避免的麻烦,从而导致效率上的问题。哼哼~果然被我找到了弱点。但是后来的一番话,差点迷惑了我。

效率提升招式之缓存: 

每个类都有单独的缓存,包含了继承的selector和类中定义的selector(只有在曾今调用过的方法才会进行缓存)。在匹配调度表之前,先检查接收对象的类缓存(哈希散列算法),如果缓存中有匹配的selector,就直接使用。这大大减少了运行时查询selector所消耗的时间。

我差点就信了。后来仔细一想,如果我连续多次调用一个特定的方法,那不就玩完了吗?哈哈哈,丫果然有弱点,看我怎么支配你。

我也算是武学奇才,一会儿就研究了一个招式:规避动态绑定机制。

首先我要想办法得到一个方法的内存地址,然后就直接调用啊,这不就没有查找selector的过程了吗。至于怎么得到方法的地址,就要靠methodForSelector方法了。请看下面的招式玩耍:

void (*showTitle)(id, SEL, NSString *);

int i;

showTitle = (void(*)(id, SEL, NSString *))[target methodForSelector:@selector(showMessage:)];

for (i=0; i<1000; ++i) {

    showTitle(targetList[i], @selector(showMessage:), "邪魔退散");

}

这样在重复多次调用一个特定的方法,有显著的效率提升。

学会了这招技能,我看着熟睡的Runtime,心想:“总有一天,在你遇到问题的时候,我会助你一臂之力的。”

不会吧,我竟然对它没有了敌意。看来在修仙的道路上,我会多一位兄弟(jiyou)了。




关注微信公众号CodingArtist,可以第一时间得到文章更新通知!  ^_^

相关文章

  • iOS Runtime修炼<二>

    基情四射的日子 我总是对神秘的事物产生兴趣,自从知道了Objective-C的Runtime技能,我便试着接近它,...

  • iOS Runtime修炼<一>

    初来乍到 由于触犯天条,被打落凡间,记忆全无,唯独iOS三个字总是被我不经意间提起。 也许冥冥之中自有安排,一个偶...

  • iOS Runtime修炼<四>

    裸露在我的面前 通过这段时间的接触,我与Runtime都觉得与彼此很合得来,于是它打算将所有的招式都展现给我。本来...

  • iOS Runtime修炼<三>

    修仙的道路不需要敌人 Runtime渐渐清醒过来,毕竟两瓶啤酒,没有多大劲,它怀疑的眼光看的我很不自在。我说:“大...

  • Mybatis中特殊符号转移

    1. 写法1 原符号替换符号<<<=<=>>>=>=<><>&&'&a...

  • test

    <script>alert(1);</script>

  • 无标题文章

    <script>alert('hello’);</script>

  • Mybatis 中大于等于小于等于的写法

    第一种写法:原符号 < <= > >= & ' "替换符号 < <= > >= &a...

  • MyBatis大于小于转义

    说明小于小于等于大于大于等于&'''原符号<<=>>=&'"替换符号<<=>>=&...

  • 初识HTML(1)

    一: 二: html编码:&;①空格 ;②<; < (less then )③>; > (gre...

网友评论

      本文标题:iOS Runtime修炼<二>

      本文链接:https://www.haomeiwen.com/subject/rflkjttx.html