美文网首页
Runtime1 -OC的消息机制

Runtime1 -OC的消息机制

作者: Jean_Lina | 来源:发表于2020-09-12 16:45 被阅读0次

OC中的方法调用底层转成了objc_msgSend函数的调用,给receiver方法调用者发送一条@selector消息。
objc_msgSend底层有3大阶段:
1:消息发送
首先根据receiver对象的isa找到类对象,在类对象的方法缓存cache中查找找到就调用,没找到在类对象的class_rw_t的方法数组method_list中遍历查找,找到就调用,并将方法缓存到类对象的cache中。没找到根据super_class指针找到父类的类对象,在父类的方法缓存中查找,找到就调用,并存入receiver类对象的方法缓存中,没找到在父类的方法列表中查找,找到就调用,并存入receiver类对象的方法缓存中,没找到继续根据super_class指针找到父类,在父类中查找。如果一直找到NSObject基类都没有找到要调用的方法,进入动态方法解析。

2:动态方法解析 resolveInstanceMethod
调用resolveInstanceMethod/resolveClassMethod动态添加方法的实现,成功添加方法实现后,该方法会存入class_rw_t的方法列表中。重新进入消息发送。如果消息发送阶段仍然没有找到要调用的方法,已经进行过一次动态方法解析,直接进入消息转发。

+ (BOOL)resolveInstanceMethod:(SEL)sel {
    if (sel == @selector(test)) {
        Method method = class_getInstanceMethod(self, @selector(testMethod));
        class_addMethod(self, sel, method_getImplementation(method), method_getTypeEncoding(method));
        return YES;
    }
    NSLog(@"%s", __func__);
    return [super resolveInstanceMethod:sel];
}
- (void)testMethod {
    NSLog(@"%s", __func__);
}

3:消息转发forwardingTargetForSelector
调用forwardingTargetForSelector方法,如果转给其他对象处理,会向返回对象发送消息。如果返回nil,没有转给其他对象处理,进入方法签名methodSignatureForSelector。如果返回的方法签名正确,进入forwardInvocaiton。

//类方法的消息转发
+ (id)forwardingTargetForSelector:(SEL)aSelector {
    if (aSelector == @selector(classMethod:)) {
        NSLog(@"forwardingTargetForSelector");
        //return [Doctor class];         //相当于objc_msgSend(Doctor, @selector(classMethod:));
        //return [[Doctor alloc] init]; //相当于objc_msgSend([[Doctor alloc] init], @selector(classMethod:));
        return nil;
    }
    return [super forwardingTargetForSelector:aSelector];
}
+ (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    if (aSelector == @selector(classMethod:)) {
        NSLog(@"methodSignatureForSelector");
        return [NSMethodSignature signatureWithObjCTypes:"i@:i"];
    }
    return [super methodSignatureForSelector:aSelector];
}
+ (void)forwardInvocation:(NSInvocation *)anInvocation {
    NSLog(@"forwardInvocation");
    int age;
    [anInvocation getArgument:&age atIndex:2];
    int ret;
    [anInvocation getReturnValue:&ret];
    NSLog(@"age = %d, ret = %d", age, ret);
}

//实例1
//拦截消息,避免报unrecognized selector send to instance错误(只有方法声明,没有方法实现)
#pragma mark 方法签名
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    if ([self respondsToSelector:aSelector]) {
        return [super methodSignatureForSelector:aSelector];
    }
    return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation {
    NSLog(@"找不到%@方法", NSStringFromSelector(anInvocation.selector));
}

//实例2
[super class]的底层实现
1:消息接收者仍然是子类对象
2:从父类开始查找方法的实现

- (Class)class {
    return object_getClass(self);
}
//获取父类对象
- (Class)superclass {
    return [self class]->superclass;
}
//Student继承Person
- (instancetype)init
{
    self = [super init];
    if (self) {
        NSLog(@"[self class] = %@", [self class]);            //Student
        NSLog(@"[self superclass] = %@", [self superclass]);   //Person
        NSLog(@"-----------------");
        NSLog(@"[super class] = %@", [super class]);          //Student
        NSLog(@"[super superclass] = %@", [super superclass]); //Person
    }
    return self;
}

相关文章

  • Runtime1 -OC的消息机制

    OC中的方法调用底层转成了objc_msgSend函数的调用,给receiver方法调用者发送一条@selecto...

  • iOS runtime

    runtime 是 oc 语音的基础首先runtime的核心机制是消息机制 也就是oc的消息机制首先oc的消息机制...

  • OC中的消息机制和动态运行时

    消息机制:OC中的实例对象调用一个方法称作消息传递 OC中里的消息传递采用动态绑定机制来决定具体调用哪个方法,OC...

  • 关于Runtime 消息发送机制的延伸

    说到OC 不得不说一下OC 的消息转发机制;何为OC 的消息转发机制;其实就是这样的; Objc 在向一个对象发送...

  • OC消息机制

    基于Runtime的动态特性 在苹果的官方文档中,对Runtime的介绍如下: The Objective-C l...

  • oc消息机制

    内存分区 1栈 局部变量 2堆alloc分配地址 在方法中(函数体)定义的变量通常是在栈内,因此如果你的变量要跨函...

  • OC消息机制

    1.消息机制RunTime简称运行时。就是系统在运行的时候的一些机制,其中最主要的是消息机制。对于C语言,函数的调...

  • OC消息机制,消息转发机制

    Runtime简称运行时,其中最主要的是消息机制 概述 C 与 OC 的不同 1.C 语言,函数的调用在编译的时候...

  • Runtime部分

    --------------------Runtime-------------------- OC的消息机制 O...

  • oc的消息机制

    import "ViewController.h" import "Person.h" // 导入框架 第一步 i...

网友评论

      本文标题:Runtime1 -OC的消息机制

      本文链接:https://www.haomeiwen.com/subject/brmwektx.html