美文网首页
OC中方法的本质

OC中方法的本质

作者: 一叶知秋0830 | 来源:发表于2019-12-13 14:48 被阅读0次

    OC中方法的定义

    OC中Method 被定义为一个objc_method结构体 指针,在这个结构体中,包含一个 SEL 和一个 IMP。

    SEL可以理解为就是一个保存方法名的字符串。需要注意的是SEL只保存了方法名,并最终要根据方法名来查找方法的实现,所以OC中是不支持方法重载的,因为方法重载时两个方法方法名相同而参数列表不同,而SEL只保存了方法名,所以重载的方法会被认为是相同的方法。(Swift是支持方法重载的。)

    IMP是一个函数指针,指向方法实现的地址。从IMP的定义可以看出其指向的函数包含一个id类型的返回值,函数至少包含2个参数,第一个参数(id)是接收消息的对象,对于实例方法来说指的是当前对象的地址,对于类方法来说指的是当前类对象的地址;第二个参数SEL就是指调用的方法。后面的省略号是方法的参数列表,所以IMP指针指向的函数的参数个数等于调用的方法的参数个数+2。

    typedef struct objc_method *Method;
    
    struct objc_method {
        SEL method_name;
        char * method_types;
        IMP method_imp;
    };
    
    // SEL
    typedef struct objc_selector *SEL;
    
    // IMP
    typedef id (*IMP)(id, SEL, ...);
    

    OC方法的调用

    OC中所有的方法调用都会转化成向对象发送消息,发送消息一般使用的是objc_msgSend函数。可以看到objc_msgSend函数的参数和返回值与IMP指向的函数的参数和返回值是一一对应的。

    id objc_msgSend(id self, SEL op, ...);
    
    • 发送消息给无参数无返回值的方法
    // 无参数无返回值的方法
    - (void)sayHello{
        NSLog(@"Hello!");
    }
    
    // 方法调用
    [self sayHello];
    
    // 发送消息给无参数无返回值的方法
    ((void (*)(id, SEL)) objc_msgSend)(self, NSSelectorFromString(@"sayHello"));
    
    • 发送消息给有参数有返回值的方法
    // 有参数有返回值的方法
    - (NSString *)combineString1:(NSString *)str1 string2:(NSString *)str2{
       return [NSString stringWithFormat:@"%@%@",str1,str2];
    }
    
    // 方法调用
    [self combineString1:@"111" string2:@"222"];
    
    // 发送消息给有参数有返回值的方法
    ((NSString *(*)(id, SEL, NSString *, NSString *)) objc_msgSend)(self, NSSelectorFromString(@"combineString1:string2:"), @"111",@"222");
    
    

    相关文章

      网友评论

          本文标题:OC中方法的本质

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