NSInvocation的使用

在iOS中方法調(diào)用的方式:
第一種方式

  • (id)performSelector:(SEL)aSelector;
  • (id)performSelector:(SEL)aSelector withObject:(id)object;
  • (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
    第二種方式
    NSInvocation
    如果參數(shù)多于兩個,比較適合使用第二種方式
#import "ViewController.h"
#import <objc/message.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
//    方法簽名
    //初始化NSMethodSignature
//    1.類方法 NSObject中的方法
//    NSMethodSignature *signature = [ViewController instanceMethodSignatureForSelector:@selector(run1:eat:)];//方法有兩個參數(shù)
//   2.對象方法 NSObject中的方法
    NSMethodSignature *signature1 = [self methodSignatureForSelector:@selector(eatFood)];//方法有一個參數(shù)
//    3.類方法 NSMethodSignature中的方法
        NSMethodSignature *signature = [NSMethodSignature signatureWithObjCTypes:"v@:@"];//此處設(shè)置了一個參數(shù)
    //此時我們應(yīng)該判斷方法是否存在藕帜,如果不存在這拋出異常
    if (signature == nil) {
        //aSelector為傳進(jìn)來的方法
        NSString *info = [NSString stringWithFormat:@"%@方法找不到", NSStringFromSelector(@selector(run:))];
        [NSException raise:@"方法調(diào)用出現(xiàn)異常" format:info, nil];
    }
//    根據(jù)方法簽名來創(chuàng)建NSInvocation對象
    //2偿洁、創(chuàng)建NSInvocation對象
    NSInvocation *invocaton = [NSInvocation invocationWithMethodSignature:signature];
//    設(shè)置方法調(diào)用者
    invocaton.target =self;
//    設(shè)置要調(diào)用的方法
    invocaton.selector = @selector(run:);//這里的方法與簽名的方法可以一致也可以不一致赶促,不一致時會調(diào)用此處設(shè)置的方法(可以在此處修改方法)
    //numberOfArguments方法獲取的參數(shù)個數(shù),包含self和_cmd埠对,減去2之后才是簽名方法中需要的參數(shù)個數(shù)
    NSArray *objects = @[@"a",@"b",@"c"];
    NSUInteger argsCount = signature.numberOfArguments-2;//簽名方法的參數(shù)個數(shù)
    NSUInteger arrCount = objects.count;
    NSUInteger count = MIN(arrCount, argsCount);
    for (int i = 0; i<count; i++) {
        id obj = objects[i];
//         判斷需要設(shè)置的參數(shù)是否是NSNull, 如果是就設(shè)置為nil
        if ([obj isKindOfClass:[NSNull class]]) {
            obj = nil;
        }
        [invocaton setArgument:&obj atIndex:i +2];// 逐個設(shè)置參數(shù)
    }
//    這里的Index要從2開始,以為0跟1已經(jīng)被占據(jù)了酬蹋,分別是self(target),selector(_cmd)
//    [invocaton setArgument:&objects atIndex:2];//簽名的方法要有參數(shù)身笤,沒有的話,會在此處崩潰斤彼,如果簽名方法的參數(shù)是兩個分瘦,此處設(shè)置一個參數(shù),那么第二個參數(shù)為nil
//    NSString *jjj;
//    [invocaton getArgument:&jjj atIndex:2];//獲得參數(shù)
//    id res = nil;
//    if (signature.methodReturnLength != 0) {//有返回值
//        //將返回值賦值給res
//        [invocaton getReturnValue:&res];//沒有返回值時琉苇,調(diào)用此方法崩潰
//    }
    [invocaton invoke];//執(zhí)行完方法后嘲玫,在往下執(zhí)行
//    NSInteger tag;
//    得到執(zhí)行方法后的返回值
//    [invocaton getReturnValue:&tag];//如果執(zhí)行的方法返回YES,tag為YES,返回NO并扇,tag為NO
//    可以通過signature.methodReturnType獲得返回的類型編碼去团,從而可以推斷返回值的具體類型
    const char *signa = signature.methodReturnType;
    NSUInteger length = signature.methodReturnLength;
    /**
     獲得返回的類型編碼,因此可以推斷返回值的具體類型
     返回類型為void穷蛹,signa=v length=0
     返回類型為NSString土陪,signa=@ length=8
     返回類型為BOOL,signa=B  length=1
     */
//    if (tag)  {
        NSLog(@"我是賈紅領(lǐng)%s**%lu",signa,(unsigned long)length);
//    }
}
-(BOOL )run2:(NSString *)method eat:(NSString *)eatStr
{
    NSLog(@"222:%@***%@",method,eatStr);
    return YES;
}
-(void)run1:(NSString *)method eat:(NSString *)eatStr
{
    NSLog(@"111:%@***%@",method,eatStr);
}
-(void)run:(NSString *)method
{
    NSLog(@"333%@",method);
}
-(void)eatFood
{
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末肴熏,一起剝皮案震驚了整個濱河市鬼雀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌扮超,老刑警劉巖取刃,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異出刷,居然都是意外死亡璧疗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進(jìn)店門馁龟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來崩侠,“玉大人,你說我怎么就攤上這事坷檩∪匆簦” “怎么了改抡?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長系瓢。 經(jīng)常有香客問我阿纤,道長,這世上最難降的妖魔是什么夷陋? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任欠拾,我火速辦了婚禮,結(jié)果婚禮上骗绕,老公的妹妹穿的比我還像新娘藐窄。我一直安慰自己,他們只是感情好酬土,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布荆忍。 她就那樣靜靜地躺著,像睡著了一般撤缴。 火紅的嫁衣襯著肌膚如雪刹枉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天屈呕,我揣著相機(jī)與錄音嘶卧,去河邊找鬼。 笑死凉袱,一個胖子當(dāng)著我的面吹牛芥吟,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播专甩,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼钟鸵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了涤躲?” 一聲冷哼從身側(cè)響起棺耍,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎种樱,沒想到半個月后蒙袍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嫩挤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年害幅,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片岂昭。...
    茶點(diǎn)故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡以现,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情邑遏,我是刑警寧澤佣赖,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站记盒,受9級特大地震影響憎蛤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜纪吮,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一蹂午、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧彬碱,春花似錦、人聲如沸奥洼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吗跋。三九已至宣脉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間瓷患,已是汗流浹背骡尽。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留擅编,地道東北人攀细。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像爱态,于是被迫代替她去往敵國和親谭贪。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評論 2 354

推薦閱讀更多精彩內(nèi)容