iOS文章

消息转发流程

2019-04-15  本文已影响32人  Code_人生
  1. 动态方法解析
  2. 备用接收者
  3. 完整消息转发
消息转发流程.png
#pragma mark - 动态方法解析
+ (BOOL)resolveInstanceMethod:(SEL)sel{

    return [super resolveInstanceMethod:sel];
}

+ (BOOL)resolveClassMethod:(SEL)sel{

    return [super resolveClassMethod:sel];
}

#pragma mark - 备用接收者
- (id)forwardingTargetForSelector:(SEL)aSelector{
    NSLog(@"%s",__func__);
//    if (aSelector == @selector(run)) {
//        // 转发给我们的LGStudent 对象
//        return [LGStudent new];
//    }
    return [super forwardingTargetForSelector:aSelector];
}

// 只有汇编调用  没有源码实现
+ (id)forwardingTargetForSelector:(SEL)aSelector{
    // 自定义处理 -- crash
    // 防止奔溃
    NSLog(@"%s",__func__);
    return [super forwardingTargetForSelector:aSelector];
}

#pragma mark - 完整消息转发
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
    NSLog(@"%s",__func__);
    if (aSelector == @selector(run)) {
        // forwardingTargetForSelector 没有实现 就只能方法签名了
        Method method    = class_getInstanceMethod(object_getClass(self), @selector(readBook));
        const char *type = method_getTypeEncoding(method);
        return [NSMethodSignature signatureWithObjCTypes:"v@:@"];
    }
    return [super methodSignatureForSelector:aSelector];
}

- (void)forwardInvocation:(NSInvocation *)anInvocation{
    NSLog(@"%s",__func__);
    NSLog(@"------%@-----",anInvocation);
    anInvocation.selector = @selector(readBook);
    [anInvocation invoke];
}

+ (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{
    NSLog(@"%s",__func__);
    if (aSelector == @selector(walk)) {
        return [NSMethodSignature signatureWithObjCTypes:"v@:@"];
    }
    return [super methodSignatureForSelector:aSelector];
}

+ (void)forwardInvocation:(NSInvocation *)anInvocation{
    NSLog(@"%s",__func__);
    
    // walk anInvocation --
    // 系统调用堆栈
    // 沙盒 -- 服务器
    
    // 切面编程
    // 家庭作业 aspect -- 消息转发代码
    
    // method-swizzling hook array 数组越界
    // self.dataArray objecAtIndex
    // if index < self.count-1 -- excepetion
    // 消息转发
    // array nil
    // 切面
    
    NSString *sto = @"奔跑少年";
    anInvocation.target = [LGStudent class];
    [anInvocation setArgument:&sto atIndex:2];
    NSLog(@"%@",anInvocation.methodSignature);
    anInvocation.selector = @selector(run:);
    [anInvocation invoke];
}
上一篇 下一篇

猜你喜欢

热点阅读