笔记-iOS消息转发机制和使用

消息转发机制的回顾以及涉及的几个方法

一、OC消息发送原理 + 消息转发机制

1、由于OC的动态特性,只有当程序运行起来之后,才知道要真正执行哪个函数(动态绑定)。在编译过程向类发送了其无法理解的消息并不会报错,因为在运行时,我们可以改变对象调用的方法、向类中添加方法。

2、OC消息发送原理、方法查找过程

(1)调用一个方法(包括respondsToSelector),编译器将OC代码,转换成C函数,给对象发送消息 : void objc_msgSend(id self, SEL cmd,…) ,第一个参数是接收者,第二个参数是方法(名),后面是消息的参数。

(2)objc_msgSend查找方法的过程:

实例对象根据其isa指针,找到其所属的class,然后遍历其methodLists,如果找到则根据IMP函数指针去调用,并且缓存(objc_cache);如果没有找到,那么根据这个类的super_class找到其父类,再看其父类是否能相应这个方法就可以了,直到super_class为nil时,就无法响应这个方法了,此时就触发消息转发机制。
当使用类名调用类方法(+方法)时,只需要根据class的isa指针,找到其meta-class,然后通过meta-class的methodLists找到相应的方法既可(“类”是“元类”的对象)。

3、如果对象接收到无法解读的消息后(未查询到该方法),就会启动“消息转发”机制,我们可在此过程告诉对象应该如何处理未知消息。如果我们不做任何处理,或处理无效,则会调用doesNotRecognizeSelector:,造成异常崩溃:unrecognized selector sent to instance 0xxx

二、消息转发机制的处理过程

消息转发机制依次的三个过程:

1、动态方法解析

第一阶段,先征询接收者所属的类,是否需要动态的添加方法,用来处理当前未找到的方法。对象在无法解读消息时会首先调用所属类的下列类方法,来判断是否能接收消息:

+ (BOOL) resolveInstanceMethod:(SEL)selector,参数为那个未知的选择子,返回值表示这个类能否新增一个实例方法处理此选择子。
如果是类方法 ,则调用  + (BOOL) resolveClassMethod:(SEL)selector,有一点要注意,类方法的添加需要在其“元类”里面。

举例:

//消息转发机制的第一步 :动态方法解析
+ (BOOL)resolveInstanceMethod:(SEL)sel{
   
   
    NSString *selName = NSStringFromSelector(sel);
    if ([selName hasPrefix:@"doSomeThing"]) {
   
   //判断特定无法响应的方法
        class_addMethod(self, sel, (IMP)otherOneDoSomeThing, "v@:");//动态添加响应方法
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}

//动态将实现转到这个函数(或者就是单纯的添加doSomeThing方法)
void otherOneDoSomeThing(id self ,SEL _cmd){
   
   
    NSLog(@"class:%@, sel:%s",self,sel_getName(_cmd));
    NSLog(@"原对象无法响应该消息,在动态方法解析时添加了一个方法来处理该消息");
}

2、备用的接收者

第二阶段,如果动态方法解析没有发现添加的方法,那么尝试转发给其他对象来处理这个方法。该步骤调用的方法是:

- (id) forwardingTargetForSelector:(SEL)selector

举例:

- (id)forwardingTargetForSelector:(SEL)aSelector{
   
   
    NSString * selString = NSStringFromSelector(aSelector
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大白砌墙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值