iOS runtime转发

104 阅读1分钟

runtime消息转发有3步:

//    [self performSelector:@selector(foo)];

//    [self performSelector:@selector(faa)];

//    [self performSelector:@selector(fcc)];

1动态方法解析

我们可以在+(BOOL)resolveInstanceMethod:(SEL)sel方法添加一个新的方法

//动态方法解析

  • (BOOL)resolveInstanceMethod:(SEL)sel {

    if(sel ==@selector(foo)) {

        class_addMethod([selfclass], sel, (IMP)fooMethod,@"v");//添加方法

        returnYES;

    }

    return [super resolveInstanceMethod:sel];

}

void fooMethod(id obj,SEL _cmd) {

\

}

2 其他接收者

如果1方法返回NO,就会来到这步,这里我们可以在- (id)forwardingTargetForSelector:(SEL)aSelector给出一个新的接收者

//备用接受者

  • (id)forwardingTargetForSelector:(SEL)aSelector {

    if(aSelector ==@selector(faa)) {

       return  [ViewController new];//新的接收者

    }

    return [super forwardingTargetForSelector:aSelector];

}

3如果第二步返回nil,就来到第三步的完整消息转发

//完整消息转发

//1获取签名

  • (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {

    if ([NSStringFromSelector(aSelector) isEqualToString:@"fcc"]) {

        return [NSMethodSignature signatureWithObjCTypes:"v@:"];;

    }

    return  [super methodSignatureForSelector:aSelector];

}

//2生成调用对象

  • (void)forwardInvocation:(NSInvocation*)anInvocation {

    SELsel = anInvocation.selector;

    person*p = [personnew];

    if ([p respondsToSelector:sel]) {

       [anInvocation invokeWithTarget:p];//完整转发

    }else{

        [self doesNotRecognizeSelector:sel];

    }

}