iOS開發(fā)之NSInvocation

一.概述

在iOS中我們直接調(diào)某個(gè)對(duì)象的消息的方式有2種

  • 系統(tǒng)NSObject類型中提供了2個(gè)方法

// 一個(gè)參數(shù)
[self performSelector:<#(SEL)#> withObject:<#(id)#>];
// 兩個(gè)參數(shù)
[self performSelector:<#(SEL)#> withObject:<#(id)#> withObject:<#(id)#>];


- 使用NSInvocation.

### 二. NSInvocation的使用

```objc
- (void)viewDidLoad {
  [super viewDidLoad];

  //方法
  SEL selector = @selector(run);
  //初始化方法簽名(方法的描述)   
   NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selector];
  // NSInvocation : 利用一個(gè)NSInvocation對(duì)象包裝一次方法調(diào)用(方法調(diào)用者、方法名、方法參數(shù)、方法返回值)
  NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
  //設(shè)置調(diào)用者
  invocation.target = self;
  //設(shè)置調(diào)用方法
  invocation.selector = selector;
  //設(shè)置參數(shù)
  NSUInteger object = 5;
  //參數(shù)從2開始,index為0表示target,1為_cmd 
  [invocation setArgument:&object atIndex:2];
  //調(diào)用方法
  [invocation invoke];

}
-(void)run:(NSInteger)num{


  NSLog(@"run");
}

三. NSInvocation實(shí)現(xiàn)多參數(shù)的封裝

系統(tǒng)的NSObject提供的performSelector的方法只提供了最多兩個(gè)參數(shù)的調(diào)用,我們可以使用NSInvocation封裝一個(gè)多個(gè)參數(shù)的performSelector方法.

#import <Foundation/Foundation.h>

@interface NSObject (MutiPerform)

-(id)performSelector:(SEL)Selector withObjects:(NSArray *)objects;
@end


#import "NSObject+MutiPerform.h"

@implementation NSObject (MutiPerform)

-(id)performSelector:(SEL)selector withObjects:(NSArray *)objects{

    //初始化方法簽名
    NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selector];
    
    // 如果方法selector不存在
    
    if(signature == nil){

        // 拋出異常
        NSString *reason = [NSString stringWithFormat:@"%@方法不存在",NSStringFromSelector(selector)];
        @throw [NSException exceptionWithName:@"error" reason:reason userInfo:nil];
    }
    
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];

    invocation.target = self;
    invocation.selector = selector;
    
    //參數(shù)個(gè)數(shù)signature.numberOfArguments 默認(rèn)有一個(gè)_cmd 一個(gè)target 所以要-2
    NSInteger paramsCount = signature.numberOfArguments - 2;
    
    // 當(dāng)objects的個(gè)數(shù)多于函數(shù)的參數(shù)的時(shí)候,取前面的參數(shù)
    //當(dāng)當(dāng)objects的個(gè)數(shù)少于函數(shù)的參數(shù)的時(shí)候,不需要設(shè)置,默認(rèn)為nil
    paramsCount = MIN(paramsCount, objects.count);
    
    for (NSInteger index = 0; index < paramsCount; index++) {
        
        id object = objects[index];

        // 對(duì)參數(shù)是nil的處理
        if([object isKindOfClass:[NSNull class]]) continue;
        
        [invocation setArgument:&object atIndex:index+2];

    }
    //調(diào)用方法
    [invocation invoke];

    // 獲取返回值
    id returnValue = nil;
    
    //signature.methodReturnLength == 0 說明給方法沒有返回值
    if (signature.methodReturnLength) {

        //獲取返回值
        [invocation getReturnValue:&returnValue];
    }
    
    return returnValue;
}


最后編輯于
?著作權(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)容

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,101評(píng)論 0 9
  • 我們常常會(huì)聽說 Objective-C 是一門動(dòng)態(tài)語言,那么這個(gè)「動(dòng)態(tài)」表現(xiàn)在哪呢?我想最主要的表現(xiàn)就是 Obje...
    Ethan_Struggle閱讀 2,351評(píng)論 0 7
  • Objective-C中有兩個(gè)NSObject,一個(gè)是NSObject類,另一個(gè)是NSObject協(xié)議。而其中NS...
    ScaryMonsterLyn閱讀 799評(píng)論 0 2
  • 目錄 Objective-C Runtime到底是什么 Objective-C的元素認(rèn)知 Runtime詳解 應(yīng)用...
    Ryan___閱讀 2,018評(píng)論 1 3
  • 像我,有時(shí)候睡下去了,就不想起來,現(xiàn)在也是在臥榻上碼字,我追求著一種安全感,可能是我從小就比較缺失吧,當(dāng)然也有...
    簡碸閱讀 237評(píng)論 0 0

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