消息机制(消息发送、动态解析、消息重定向)

第一步、消息发送

#import 

    // 创建person对象
    person *p = [[person alloc] init];

    // 调用对象方法
    [p eat];

    // 本质:让对象发送消息(对象方法)
    objc_msgSend(p, @selector(eat));

    // 本质:让类对象发送消息(类方法)
    objc_msgSend([person class], @selector(sleep));

第二步、动态解析

第三步、消息重定向

屏幕快照 2020-07-27 上午11.37.52.png
- (void)viewDidLoad {

    [super viewDidLoad];

    [self performSelector:@selector(eat)];

}

/***第一次、动态解析***/
+(BOOL)resolveInstanceMethod:(SEL)sel
{

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

        class_addMethod([self class], sel, (IMP)funMethod, "v@:");

    }

    return YES;

}

void funMethod(id obj,SEL _cmd) {

    NSLog(@"funMethod"); //新的 fun 函数

}

/***第二次、接受者消息重定向***/
- (id)forwardingTargetForSelector:(SEL) aSelector
{

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

        person * p = [[person alloc]init];

        return p;

    }

    return nil;

}

/***第三次、获取函数的参数和返回值类型,返回签名***/
- (NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector {
    if ([NSStringFromSelector(aSelector) isEqualToString:@"eat"]) {

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

    }

    return [super methodSignatureForSelector:aSelector];

}

/***第三次、消息重定向***/
- (void)forwardInvocation:(NSInvocation*)anInvocation {
    SEL sel = anInvocation.selector;  // 从 anInvocation 中获取消息

    person * p = [[person alloc]init];

    if([p respondsToSelector:sel]) {  // 判断 Person 对象方法是否可以响应 sel

        [anInvocation invokeWithTarget:p];  // 若可以响应,则将消息转发给其他对象处理

    }else{

        [self doesNotRecognizeSelector:sel];  // 若仍然无法响应,则报错:找不到响应方法

    }

}

@end

你可能感兴趣的:(消息机制(消息发送、动态解析、消息重定向))