赞
踩
NSLog(@"SHOW TIME...");
当我们调用方法时,比如[obj class],就是向obj所属的类发送一条消息,那么系统是如何发送这条消息的?它是如何帮我们找到对应的方法实现的?要是找不到对应的方法实现怎么办?接下来跟我一起探索OC的 传递和消息转发吧⏬
在系统运行编译时,会将[obj class]转换成C函数objc_msgSend(obj, @selector(class))
如[obj class],通过obj的isa指针找到obj对应的父类class,从类class的缓存cache中找到同名的函数实现(IMP);如果缓存中没有,就去class的方法列表(methodList)中查找;如果依旧没有找到,则根据类class的isa指针向上找到父类superClass,再按序从父类的缓存和方法列表中查找;通过isa指针逐级找到父类直到根元类HomeClass,如果期间找到了方法的函数实现,就调用函数指针到对应的函数进行执行,如果此时仍然未找到就进入消息转发流程。流程如图1-1
图1-1 消息传递流程简略图
- 在缓存cache中,通过哈希算法进行匹配查找;
- 在类方法中有2种查找方式:①对于有序排列的方法列表采用二分查找算法;②无序排列的方法列表采用一般遍历。
如果在消息传递过程中未找到同名的函数方法,就会进入消息转发流程,首先会调用当前类的类方法:
+ (BOOL)resolveInstanceMethod:(SEL)selector
如果这个列方法中实现了同名函数方法,返回结果YES,结束转发流程;如果返回NO,系统给我们第二次机会来处理这个消息,调用方法如下:
- (id)forwardingTargetForSelector:(SEL)aSelector
在forwardingTargetForSelector方法中会返回消息转发目标,如果目标存在则结束转发,如果不存在系统给第三次机会处理消息,调用方法如下:
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
此时如果返回依旧为nil,就会无法处理消息产生crash。
NSLog(@"END...");
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。