03.消息机制
OC
中调用方法称为消息传递
OC
中消息传递采用动态绑定机制来决定具体调用哪个方法,但OC
不是在编译时决定调用什么方法而是在运行时决定
转换为CPP
将.m
转换为.cpp
的clang
命令
OC
CPP
调用方法时具体发生了什么呢?
现在本类的方法缓存列表中寻找有没有对应方法,如果有就执行
如果没有缓存的,就在本类的犯法列表中查找,找到了就执行
如果没找到,就到父类中查找,找到了就执行
没找到,进入下面的流程
消息处理-ResolveMethod
如果沿继承树没有找到相关方法则会向接受者所属的类进行一次请求,看能否动态添加一个方法
在相应的类及父类中找不到方法实现的话会执行
+ (BOOL)resolveInstanceMethod:(SEL)sel
这个方法,如果没重写的话会返回NO
在该方法中我们可以为找不到实现的
SEL
添加一个实现.这样就能防止调用一个不存在的方法时崩溃.
消息单项转发
当
resolveInstanceMethod
返回NO
,就会进入消息转发阶段- (id)forwardingTargetForSelector: (SEL)aSelector
该方法会返回一个累的对象,该对象包含
SEL
对应的实现.如果返回nil
或self
的话说明找不到相应的转发进入下一步
消息多项转发
如果不将消息转发给其他对象就只能自己处理或者崩溃了
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
获取方法的参数及返回数据类型,也就是说获取的是该方法的签名并返回,进入下一步
返回
NSMethodSignature
为nil
的话不会进入下一步,抛出异常
具体的实现方式不再展开, 每种数据类型都有对应的符号代表,根据一定规则生成描述
- (void)forwardInvocation:(NSInvocation *)anInvocation
runtime
将要转发的消息封装为NSInvocation
调用- (void)forwardInvocation: (NSInvocation*)invocation;
在这个函数里可以将NSInvocation多次转发到多个对象中
调用这个方法如果不能处理就会调用父类的相关方法,一直到
NSObject
的这个方法如果
NSObject
都无法处理就会调用doesNotRecognizeSelector:
方法抛出异常
NSInvocation
有点类似于java
里的反射,它有一套完整的装备:target
,selector
,returnValue
,ArgumentArray
,有了它们,NSInvocation
就可以动态的invoke
任意对象的任意方法了。
参考
Last updated