OC底层09:消息流程-三级容错机制

前言

上章说到系统没有找到对应的方法实现时会进入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);
        }
    }

类方法的查找与实例方法的查找不同。
类方法的查找:

  1. 先找类的resolveClassMethod
  2. 再找元类及父类的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:不执行,系统也不会崩溃,但浪费了性能。
整个容错机制如图:


你可能感兴趣的:(OC底层09:消息流程-三级容错机制)