iOS开发之旅--_isa和_imp指针

iOS开发之旅--_isa和_imp指针

    

一、回顾_isa指针

之前谈到过isa指针,isa指针是一个指向所属类的指针,它标注着一个实例对象的真实类型。

在Object-C中消息机制是依靠objc_msgSend()这个函数发送消息,

objc_msgSend含两个参数:receiver、selector。即:objc_msgSend(receiver, selector);

而objc_msgSend通过isa指针,找到实例对象所属的类,也就找到了其全部父类,如下图所示:

一个方法被调用要经过的真实步骤是这样的:当我门向一个对象发送消息去调用他的方法时,objc_msgSend会根据该实例对象的isa指针去查找该对象的类,然后去查找该类的disptach table中的selector,如果找不到就会依次向上查找它的父类,并在其父类的dispatch table中查找相应的selector,直到NSObject类。一旦找到该selector,objc_msgSend会根据dispatch table中内存地址去调用该selector。这样实现message和selector在执行阶段的动态绑定。为了提高这种查找转发的效率。系统会把所有的selector内存地址和调用过的selector的内存地址缓存起来。而通过类的形式划分不同的缓存区域。每一个类的缓存区域会包括自己的selector和继承自父类的selector,在objc_msgSend去查找disptach table前,会先去检查该类的缓存。如果缓存命中,就直接调用selecotr。

二、了解_imp指针

imp是implementation的缩写,顾名思义imp指针是指向selector的具体实现的指针。在了解IMP指针之前,来探讨一个问题,现在需求是在不影响层级结构和尽量少改动的情况下,让项目中所有viewController的ViewDidLoad方法中打印自己的类型。了解Runtime的同学,可能会想到

method_exchangeImplementations(Method m1, Method m2)


这种方式很轻松的实现了我门的需求,但是作为一个优雅的程序员,就要做优雅的事情。下面就来imp指针。

首先要配置工程

进行如下配置:

 

配置完成,直接上代码:

 

使用imp指针更改方法实现成功。这样做比上一种方式更加优雅。

 

接下来探讨一下method_exchangeImplementations(Method m1, Method m2)方法的实现原理:

从imp指针的地址打印来看貌似这个方法是将两个方法的imp指针做了互换。

 

经过这么多代码的测试,最终印证的还是那句话,imp指针是指向selector具体实现的指针。

附加一下真实imp的具体定义:

转载于:https://my.oschina.net/fadoudou/blog/1799795

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值