iOS中NSInvocation的基本用法教程
前言
大家應該都有所了解,在 iOS中可以直接調(diào)用某個對象的消息方式有兩種:一種是performSelector:withObject;再一種就是NSInvocation。
第一種方式比較簡單,能完成簡單的調(diào)用。但是對于>2個的參數(shù)或者有返回值的處理,那performSelector:withObject
就顯得有點有心無力了,那么在這種情況下,我們就可以使用NSInvocation來進行這些相對復雜的操作
NSInvocation的基本使用
方法簽名類
// 方法簽名中保存了方法的名稱/參數(shù)/返回值,協(xié)同NSInvocation來進行消息的轉(zhuǎn)發(fā) // 方法簽名一般是用來設置參數(shù)和獲取返回值的, 和方法的調(diào)用沒有太大的關(guān)系 //1、根據(jù)方法來初始化NSMethodSignature NSMethodSignature *signature = [ViewController instanceMethodSignatureForSelector:@selector(run:)];
根據(jù)方法簽名來創(chuàng)建NSInvocation對象
// NSInvocation中保存了方法所屬的對象/方法名稱/參數(shù)/返回值 //其實NSInvocation就是將一個方法變成一個對象 //2、創(chuàng)建NSInvocation對象 NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; //設置方法調(diào)用者 invocation.target = self; //注意:這里的方法名一定要與方法簽名類中的方法一致 invocation.selector = @selector(run:); NSString *way = @"byCar"; //這里的Index要從2開始,以為0跟1已經(jīng)被占據(jù)了,分別是self(target),selector(_cmd) [invocation setArgument:&way atIndex:2]; //3、調(diào)用invoke方法 [invocation invoke]; //實現(xiàn)run:方法 - (void)run:(NSString *)method{ }
優(yōu)化
但是上述方法有很多弊端,首先我們來一一解決
1、如果調(diào)用的方法不存在
//此時我們應該判斷方法是否存在,如果不存在這拋出異常 if (signature == nil) { //aSelector為傳進來的方法 NSString *info = [NSString stringWithFormat:@"%@方法找不到", NSStringFromSelector(aSelector)]; [NSException raise:@"方法調(diào)用出現(xiàn)異常" format:info, nil]; }
2、方法的參數(shù)個數(shù)與外界傳進來的參數(shù)數(shù)組元素個數(shù)不符
//此處不能通過遍歷參數(shù)數(shù)組來設置參數(shù),因為外界傳進來的參數(shù)個數(shù)是不可控的 //因此通過numberOfArguments方法獲取的參數(shù)個數(shù),是包含self和_cmd的,然后比較方法需要的參數(shù)和外界傳進來的參數(shù)個數(shù),并且取它們之間的最小值 NSUInteger argsCount = signature.numberOfArguments - 2; NSUInteger arrCount = objects.count; NSUInteger count = MIN(argsCount, arrCount); for (int i = 0; i < count; i++) { id obj = objects[i]; // 判斷需要設置的參數(shù)是否是NSNull, 如果是就設置為nil if ([obj isKindOfClass:[NSNull class]]) { obj = nil; } [invocation setArgument:&obj atIndex:i + 2]; }
3、判斷當前調(diào)用的方法是否有返回值
//方法一: id res = nil; if (signature.methodReturnLength != 0) {//有返回值 //將返回值賦值給res [invocation getReturnValue:&res]; } return res; //方法二: //可以通過signature.methodReturnType獲得返回的類型編碼,因此可以推斷返回值的具體類型
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
iOS 中 使用UITextField格式化銀行卡號碼的解決方案
今天小編給大家分享ios中使用UITextField格式化銀行卡號碼的實現(xiàn)思路詳解,非常不錯,具有參考借鑒價值,需要的朋友參考下2016-12-12iOS實現(xiàn)類似微信和支付寶的密碼輸入框(UIKeyInput協(xié)議)
這篇文章主要介紹了iOS實現(xiàn)類似微信和支付寶的密碼輸入框,通過UIKeyInput協(xié)議為響應者提供簡單的鍵盤輸入的功,再通過CoreGraphics繪制出密碼輸入框,感興趣的小伙伴們可以參考一下2016-08-08iOS開發(fā)中對文件目錄的訪問及管理的基本方法小結(jié)
這篇文章主要介紹了iOS開發(fā)中對文件目錄的訪問及管理的基本方法小結(jié),代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下2015-10-10IOS 圖文混排(CoreText.framework)詳解及實例
這篇文章主要介紹了IOS 圖文混排(CoreText.framework)詳解及實例的相關(guān)資料,這里對IOS 的圖文混排進行了詳細介紹,并附代碼實例,和實現(xiàn)效果圖,需要的朋友可以參考下2016-11-11