iOS關(guān)于RuntimeInvoker

RuntimeInvoker是一個(gè)Objective-C反射調(diào)用庫的封裝。

https://github.com/cyanzhong/RuntimeInvoker
以下是一些簡單的使用舉例:

-(void)test{
    NSString *s = [self invoke:@"fun1"];
    NSLog(@"---------%@",s);
}

-(NSString *)fun1{
   return @"fun1";
}
-(void)test{
    [self invoke:@"fun2:" args:@(YES),nil];
}

-(void)fun2:(BOOL)bo{
    if (bo) {
        NSLog(@"fun2 yes");
    }else{
        NSLog(@"fun2 no");
    }
}
-(void)test{
    NSString *s = [[self class] invoke:@"fun3:" args:@"abc",nil];
    NSLog(@"---------%@",s);
}

+(NSString *)fun3:(NSString *)str{
    return [NSString stringWithFormat:@"fun3 %@",str];
}
-(void)test{
    NSString *s = [@"AppDelegate" invokeClassMethod:@"fun4:" args:@"abc",nil];
    NSLog(@"---------%@",s);
}

+(NSString *)fun4:(NSString *)str{
    return [NSString stringWithFormat:@"fun4 %@",str];
}

如果類是由字符串過去的,需要用invokeClassMethod替換invoke。

遇到這樣一個(gè)問題,方法如下:

-(void)callFun6:(NSString *)str1 index:(int)index f:(CGFloat)f point:(CGPoint)p;

我在拿到類對(duì)象的情況下,需要調(diào)用這個(gè)函數(shù),該怎么做?
見下面代碼:

        TartetObject *target = [TartetObject new];
        id obj = target;
        NSString *str1 = @"2";
        NSInteger index = 3;
        CGFloat f = 3.1415926;
        NSString *selStr = @"callFun6:index:f:point:";
//        SEL sel = NSSelectorFromString(selStr);
        CGPoint point = CGPointMake(32.121, 195.321);
        [obj invoke:selStr args:str1,[NSNumber numberWithInt:index],[NSNumber numberWithFloat:f],[NSValue valueWithCGPoint:point],nil];

執(zhí)行,會(huì)發(fā)現(xiàn)CGpoint沒有傳值成功。閱讀RuntimeInvoker代碼可以發(fā)現(xiàn)作者在invocationWithArguments函數(shù)中少寫了一部分代碼。

后面補(bǔ)上point的類型

     case RIMethodArgumentTypeCGPoint: {
                CGPoint p = [argument CGPointValue];
                [invocation setArgument:&p atIndex:index];
            } break;

再跑一遍,傳參數(shù)成功了!

如果參數(shù)帶有block該怎么處理呢?

函數(shù)原型如下:

-(void)callFun6:(NSString *)str1 index:(int)index f:(CGFloat)f point:(CGPoint)p callBack:(void(^)(NSString *))block{
    NSLog(@"callFun6 = %@%d%.2f;x=%.2fy=%.2f",str1,index,f,p.x,p.y);
    block(@"abcdefg");
}

調(diào)用他:

        TartetObject *target = [TartetObject new];
        id obj = target;
        NSString *str1 = @"2";
        NSInteger index = 3;
        CGFloat f = 3.1415926;
        NSString *selStr = @"callFun6:index:f:point:callBack:";
        CGPoint point = CGPointMake(32.121, 195.321);
        
        void (^callblock)(NSString*) = ^(NSString * str){
            NSLog(@"------------%@",str);
            [target callFun1];
        };
        [obj invoke:selStr args:str1,[NSNumber numberWithInt:index],[NSNumber numberWithFloat:f],[NSValue valueWithCGPoint:point],callblock,nil];

發(fā)現(xiàn)出錯(cuò)了,block傳過來是空的。

看下RuntimeInvoker代碼,是的確沒有處理參數(shù)是block的情況。我們手動(dòng)改一下,代碼如下:

在判斷為未知類型的情況下,看下這個(gè)類是否是block。如果是block,就直接把參數(shù)傳遞過去。當(dāng)然,在未知情況下直接把參數(shù)傳遞過去也是可以的。

好了,RuntimeInvoker基本上可以滿足我們?nèi)粘J褂眯枨罅恕?/p>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • iOS網(wǎng)絡(luò)架構(gòu)討論梳理整理中。。。 其實(shí)如果沒有APIManager這一層是沒法使用delegate的,畢竟多個(gè)單...
    yhtang閱讀 5,489評(píng)論 1 23
  • *面試心聲:其實(shí)這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,603評(píng)論 30 472
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,641評(píng)論 18 399
  • 前言 人生苦多,快來 Kotlin ,快速學(xué)習(xí)Kotlin! 什么是Kotlin? Kotlin 是種靜態(tài)類型編程...
    任半生囂狂閱讀 26,686評(píng)論 9 118
  • 在這個(gè)社會(huì)上有那么一部分人,白天扮演著不同的角色,擁有著眾多的身份 她們是學(xué)生、是白領(lǐng)又或者是醫(yī)生,夜幕降臨她們褪...
    西街舊巷的老貓l閱讀 229評(píng)論 0 0

友情鏈接更多精彩內(nèi)容