OC底层09:消息流程-三级容错机制
2020-10-21 本文已影响0人
ZAREMYDREAM
前言
上章说到系统没有找到对应的方法实现时会进入resolveInstanceMethod
动态决议流程。而实际消息流程中有三层容错机制:动态决议->快速转发->慢速转发。
动态决议
if (! cls->isMetaClass()) {
// try [cls resolveInstanceMethod:sel]
resolveInstanceMethod(inst, sel, cls);
}
else {
// try [nonMetaClass resolveClassMethod:sel]
// and [cls resolveInstanceMethod:sel]
resolveClassMethod(inst, sel, cls);
if (!lookUpImpOrNil(inst, sel, cls)) {
resolveInstanceMethod(inst, sel, cls);
}
}
类方法的查找与实例方法的查找不同。
类方法的查找:
- 先找类的
resolveClassMethod
- 再找元类及父类的
resolveInstanceMethod
原因:因为类方法实际是存放在元类的实例方法。
动态决议流程
创建一个Person
类,定义- (void)test1
与+(void)test2
不实现。
调用执行这两个方法。
在Person
中实现:
运行结果如图:
快速转发流程
当动态决议未处理时,会进入快速转发流程- (id)forwardingTargetForSelector:(SEL)aSelector;
快速转发流程及给消息指定一个接收者。
定义一个
Teaher
类实现test1
方法,然后再Person
中实现:
- (id)forwardingTargetForSelector:(SEL)aSelector {
NSLog(@"%@", NSStringFromSelector(aSelector));
return [Teacher alloc];
}
执行结果如图:
慢速转发
当快速转发也不做处理时,进入慢速转发流程,系统不会做过多的处理,会将其当做事务抛出,谁需要谁去处理该方法。
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
NSLog(@"%@", anInvocation);
}
如果谁需要这个方法,只需指定
target
- (void)forwardInvocation:(NSInvocation *)anInvocation {
anInvocation.target = [Teacher alloc];
[anInvocation invoke];
}
ps:不执行,系统也不会崩溃,但浪费了性能。
整个容错机制如图: