iOS之使用NSInvocation調(diào)用方法

在iOS開發(fā)中硼补,我們一般會(huì)使用以下兩種方式去調(diào)用一個(gè)方法
(1) [obj methodName];
(2) [obj performSelector......];

兩種方式各自的缺點(diǎn)

1.方法參數(shù)過多的情況
- (NSString *)append:(NSString *)str1 withStr2:(NSString *)str2 andStr3:(NSString *)str3 {
    NSString *str = [str1 stringByAppendingString:str2];
    str = [str stringByAppendingString:str3];
    return str;
}

兩種方式執(zhí)行方法的代碼如下


看看打印結(jié)果


方式一的打印結(jié)果是沒有問題的
方式二由于最多只能傳遞兩個(gè)參數(shù)兴泥,所以最后一個(gè)參數(shù)的值是不準(zhǔn)確的

由此可以得出萄金,方式二的缺點(diǎn)就是不能執(zhí)行參數(shù)過多的方法

2.方法名為字符串的情況

用方式一顯然是不可以的


編譯報(bào)錯(cuò),有人可能就要說了显蝌,直接[self printName:@"Tom"]不就行了沾谓,如果這樣認(rèn)為荚坞,那就沒必要往下看了,這僅僅只是個(gè)例子今妄,在真實(shí)開發(fā)中郑口,這個(gè)字符串可能是程序運(yùn)行過程中才獲取的。

此時(shí)方式二的優(yōu)勢(shì)就體現(xiàn)出來(lái)了盾鳞,我們來(lái)看看方式二是如何執(zhí)行方法的


完美運(yùn)行


由此可以得出犬性,方式一不能通過方法名字符串來(lái)執(zhí)行方法

那有沒有一種方式,既可以通過方法名字符串來(lái)調(diào)用方法腾仅,也可以傳遞很多參數(shù)呢仔夺?答案肯定是有的,要不然筆者何必在這里廢話呢

NSInvocation的簡(jiǎn)單使用

例:要執(zhí)行如下方法攒砖,但只知道方法名字符串

//方法名字符串
NSString *methodNameStr = @"test:withArg2:andArg3:";
//要執(zhí)行的方法
- (void)test:(NSString *)arg1 withArg2:(NSString *)arg2 andArg3:(NSString *)arg3 {
    NSLog(@"%@---%@---%@", arg1, arg2, arg3);
}

1.創(chuàng)建一個(gè)方法簽名

//NSObject的對(duì)象方法缸兔,任何繼承自NSObject的對(duì)象都可以調(diào)用
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
//NSObject的類方法,任何繼承自NSObject的類都可以調(diào)用
+ (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector
注意

上面的兩個(gè)方法中吹艇,aSelector參數(shù)惰蜜,不一定是你要調(diào)用的那個(gè)方法,可以是任意方法受神,但是該方法的參數(shù)個(gè)數(shù)必須與你要調(diào)用的參數(shù)個(gè)數(shù)一致

我們一般使用self來(lái)創(chuàng)建方法簽名

SEL selector = NSSelectorFromString(methodNameStr);
NSMethodSignature *signature = [self methodSignatureForSelector:selector];
//或使用下面這種方式
NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:selector];

NSMethodSignature有兩個(gè)常用的只讀屬性
a. numberOfArguments:方法參數(shù)的個(gè)數(shù)
b. methodReturnLength:方法返回值類型的長(zhǎng)度抛猖,大于0表示有返回值

2.使用方法的簽名來(lái)創(chuàng)建一個(gè)NSInvocation對(duì)象

NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
//只能使用該方法來(lái)創(chuàng)建,不能使用alloc init

3.給invocation的兩個(gè)屬性賦值
要執(zhí)行誰(shuí)的(target)的哪個(gè)方法(selector)

invocation.target = self;
invocation.selector = selector;

4.給要執(zhí)行的方法設(shè)置參數(shù)
使用setArgument:atIndex:方法給要執(zhí)行的方法設(shè)置參數(shù),注意下標(biāo)從2開始财著,因?yàn)?联四、1已經(jīng)被target與selector占用

NSString *arg1 = @"a";
NSString *arg2 = @"b";
NSString *arg3 = @"c";
[invocation setArgument:&arg1 atIndex:2];
[invocation setArgument:&arg2 atIndex:3];
[invocation setArgument:&arg3 atIndex:4];

設(shè)置參數(shù),必須傳遞參數(shù)的地址撑教,不能直接傳值
5.執(zhí)行方法

[invocation invoke];

運(yùn)行結(jié)果如下


如果方法有返回值呢朝墩?如何獲取方法的返回值?
我們修改一下要調(diào)用的方法伟姐,增加一個(gè)返回值收苏,如下所示

- (NSString *)test:(NSString *)arg1 withArg2:(NSString *)arg2 andArg3:(NSString *)arg3 {
    NSLog(@"%@---%@---%@", arg1, arg2, arg3);
    return @"haha";
}

要想獲取返回值,我們只需要在之前的基礎(chǔ)上增加兩行代碼

//可以在invoke方法前添加愤兵,也可以在invoke方法后添加
//通過方法簽名的methodReturnLength判斷是否有返回值
if (signature.methodReturnLength > 0) {
    id *result = nil;
    [invocation getReturnValue:&result];
}

注意獲取返回值與設(shè)置參數(shù)一樣鹿霸,都必須將地址傳過去

最后將完整的代碼及運(yùn)行結(jié)果貼上


運(yùn)行結(jié)果


總的來(lái)說,NSInvocation的使用還是很簡(jiǎn)單的秆乳,只是步驟有點(diǎn)繁瑣
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末懦鼠,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子屹堰,更是在濱河造成了極大的恐慌葛闷,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件双藕,死亡現(xiàn)場(chǎng)離奇詭異淑趾,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)忧陪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門扣泊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人嘶摊,你說我怎么就攤上這事延蟹。” “怎么了叶堆?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵阱飘,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我虱颗,道長(zhǎng)沥匈,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任忘渔,我火速辦了婚禮高帖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘畦粮。我一直安慰自己散址,他們只是感情好乖阵,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著预麸,像睡著了一般瞪浸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吏祸,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天对蒲,我揣著相機(jī)與錄音,去河邊找鬼犁罩。 笑死齐蔽,一個(gè)胖子當(dāng)著我的面吹牛两疚,可吹牛的內(nèi)容都是我干的床估。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼诱渤,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼丐巫!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起勺美,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤递胧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后赡茸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缎脾,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年占卧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了遗菠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡华蜒,死狀恐怖辙纬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情叭喜,我是刑警寧澤贺拣,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站捂蕴,受9級(jí)特大地震影響譬涡,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜啥辨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一昂儒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧委可,春花似錦渊跋、人聲如沸腊嗡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)燕少。三九已至,卻和暖如春蒿囤,著一層夾襖步出監(jiān)牢的瞬間客们,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工材诽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留底挫,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓脸侥,卻偏偏與公主長(zhǎng)得像建邓,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子睁枕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

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

  • 第5章 引用類型(返回首頁(yè)) 本章內(nèi)容 使用對(duì)象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學(xué)一百閱讀 3,233評(píng)論 0 4
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理官边,服務(wù)發(fā)現(xiàn),斷路器外遇,智...
    卡卡羅2017閱讀 134,654評(píng)論 18 139
  • 年末跳仿,一朵雪诡渴,撫慰著舊去的歲月。驀然轉(zhuǎn)身菲语,你在妄辩,我在,我們都在谨究,如此恩袱,溫暖。 遇見了久違的你胶哲,遇見了我想遇見的你畔塔,...
    牧塵Muchen閱讀 812評(píng)論 6 10
  • 您不辛的點(diǎn)開了篇小說,如果我有辛讓您看完了鸯屿,那么給個(gè)意見好嗎澈吨?謝謝! 在坐了兩天的火車后寄摆,兩人終于到達(dá)A市谅辣。 因...
    1919忘千愁閱讀 491評(píng)論 0 0