OC方法调用的四种方式

简介:

  OC中方法调用分为四种方式,如下:

  1. OC代码调用;
  2. NSObject的performSelector调用;
  3. NSInvocation调用;
  4. objc_msgSend即runtime底层方法调用。
      我们最熟悉的当然1和2,我们经常用到,是OC层面上的调用;而3涉及到了方法的动态解析和消息转发机制;4中objc_msgSend调用,是runtime层方法的调用,其实上述的1、2、3到底层runtime层,都是通过objc_msgSend进行调用的,也就是OC的消息发送机制。该篇文章不讲述其它,只是简单对方法调用进行记录和说明。

OC代码调用:

// .h文件
@interface ZBYRunTimePersionModel : NSObject

/// 消息调用的四种方法
- (NSString *)callTestWithStr1:(NSString *)str1 str2:(NSString *)str2 str3:(NSString *)str3;

@end

// .m文件
@implementation ZBYRunTimePersionModel

- (NSString *)callTestWithStr1:(NSString *)str1 str2:(NSString *)str2 str3:(NSString *)str3 {
    NSString * result = [NSString stringWithFormat:@"%@-%@-%@", str1, str2, str3];
    return result;
}

@end

    // OC代码直接调用
    ZBYRunTimePersionModel * person = [ZBYRunTimePersionModel new];
    NSString * r1 = [person callTestWithStr1:@"a" str2:@"b" str3:@"c"];
    NSLog(@"%@", r1);

  最常用的方式,直接调用,缺点不能通过方法名字符串来执行方法。

NSObject的performSelector调用:

    // 2.1用方法调用
    NSString * r21 = [person performSelector:@selector(callTestWithStr1:str2:str3:) withObject:@"a" withObject:@"b"];
    NSLog(@"%@", r21);
    
    // 2.2用方法对应的字符串初始化为方法,再进行调用
    SEL selected = NSSelectorFromString(@"callTestWithStr1:str2:str3:");
    NSString * r22 = [person performSelector:selected withObject:@"a" withObject:@"b"];
    NSLog(@"%@", r22);

  通过NSObject继承的底层方法进行调用;无法进行2个以上参数的传递。

NSInvocation调用:

    /**
     3.NSInvocation调用方法
     3.1进行方法签名;NSMethodSignature的两个参数:numberOfArguments方法参数的个数;methodReturnLength方法返回值类型
        的长度,大于0表示有返回值
     3.2初始化NSInvocation并设置参数
        第一个参数下标为0是target,及响应者;
        第二个参数是selector,及需要调用的方法;
        第三个起是自定义参数,必须传递参数的地址,不能直接传值,例如:str1,str2,str3
     3.3获取返回值;可以在调用invoke前,也可以在invoke之后
     */
    NSMethodSignature * sign = [person methodSignatureForSelector:selected];
    
    // 或者
//    NSMethodSignature * sign = [[self class] instanceMethodSignatureForSelector:selected];
    NSInvocation * invocation = [NSInvocation invocationWithMethodSignature:sign];
    invocation.target = person;
    invocation.selector = selected;
    NSString *arg1 = @"a";
    NSString *arg2 = @"b";
    NSString *arg3 = @"c";
    [invocation setArgument:&arg1 atIndex:2];
    [invocation setArgument:&arg2 atIndex:3];
    [invocation setArgument:&arg3 atIndex:4];
    [invocation invoke];
    if (sign.methodReturnLength > 0) {
        NSString * result = nil;
        [invocation getReturnValue:&result];
        NSLog(@"%@", result);
    }
    else {
        NSLog(@"没有返回值")
    }

  需要对方法进行签名。

objc_msgSend即runtime底层方法调用:

    // 4.第四种方法:底层调用,方法到底层都是通过objc_msgSend调用的,直接用objc_msgSend强制转换进行调用
    
    // 4.1强制转换和调用分开
    void *(*zby_runtime_msgObserverSend)(id, SEL, void *, void *, void *) = (void *)objc_msgSend;
    NSString * r = (__bridge NSString *)(zby_runtime_msgObserverSend(person, selected, @"a", @"b", @"c"));
    NSLog(@"%@", r);
    
    // 4.2强制转换和调用一起
    ((void(*)(id, SEL, void *, void *, void *))objc_msgSend)(person, selected, @"a", @"b", @"c");
//    NSString * r2 = (__bridge NSString *)((void(*)(id, SEL, void *, void *, void *))objc_msgSend)(person, selected, @"a", @"b", @"c");
//    NSLog(@"%@", r2);
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容