NSMethodSignature和NSInvocation的一些用法

NSMethodSignature顧名思義應(yīng)該就是“方法簽名”革答,類似于C++中的編譯器時的函數(shù)簽名榄融。蘋果官方定義該類為對方法的參數(shù)缕贡、返回類似進行封裝某饰,協(xié)同NSInvocation實現(xiàn)消息轉(zhuǎn)發(fā)儒恋。通過消息轉(zhuǎn)發(fā)實現(xiàn)類似C++中的多重繼承。

iOS中的SEL黔漂,它的作用和C诫尽、C++中的函數(shù)指針很相似,通過performSelector:withObject:函數(shù)可以直接調(diào)用這個消息炬守。但是perform相關(guān)的這些函數(shù)牧嫉,有一個局限性,其參數(shù)數(shù)量不能超過2個减途,否則要做很麻煩的處理酣藻,與之相對,NSInvocation也是一種消息調(diào)用的方法鳍置,并且它的參數(shù)沒有限制辽剧。這兩種直接調(diào)用對象消息的方法,在IOS4.0之后税产,大多被block結(jié)構(gòu)所取代怕轿,只有在很老的兼容性系統(tǒng)中才會使用。
簡單用法如下:
- (void)test {
int a = 1;
int b = 2;
int c = 3;
SEL myMethod = @selector(myLog:param:parm:);
SEL myMethod2 = @selector(myLog);
// 創(chuàng)建一個函數(shù)簽名辟拷,這個簽名可以是任意的撞羽,但需要注意,簽名函數(shù)的參數(shù)數(shù)量要和調(diào)用的一致衫冻。
NSMethodSignature *sig = [[self class] instanceMethodSignatureForSelector:myMethod];
// 通過簽名初始化
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig];
// 2.FirstViewController *view = self;
// 2.[invocation setArgument:&view atIndex:0];
// 2.[invocation setArgument:&myMethod2 atIndex:1];
// 設(shè)置target
// 1.[invocation setTarget:self];
// 設(shè)置selector
[invocation setSelector:myMethod];
// 注意:1诀紊、這里設(shè)置參數(shù)的Index 需要從2開始,因為前兩個被selector和target占用隅俘。
[invocation setArgument:&a atIndex:2];
[invocation setArgument:&b atIndex:3];
[invocation setArgument:&c atIndex:4];
// [invocation retainArguments];
// 我們將c的值設(shè)置為返回值
[invocation setReturnValue:&c];
int d;
// 取這個返回值
[invocation getReturnValue:&d];
NSLog(@"d:%d", d);

   NSUInteger argCount = [sig numberOfArguments];
   NSLog(@"argCount:%ld", argCount);

   for (NSInteger i=0; i<argCount; i++) {
       NSLog(@"%s", [sig getArgumentTypeAtIndex:i]);
   }
   NSLog(@"returnType:%s ,returnLen:%ld", [sig methodReturnType], [sig methodReturnLength]);
   NSLog(@"signature:%@" , sig);

   // 消息調(diào)用
   2.[invocation invokeWithTarget:self];
}

注意:代碼中用1.標識的為第一種用法邻奠,通過setTarget和setSelector來設(shè)置NSInvocation的參數(shù),而用2.標識的是另一種用法为居,通過setArgument atIndex:來設(shè)置參數(shù)惕澎。看個人的喜好颜骤。唧喉。。

- (int)myLog:(int)a param:(int)b parm:(int)c
{
     NSLog(@"MyLog:%d,%d,%d", a, b, c);
     return a+b+c;
}

- (void)myLog
{
     NSLog(@"你好,South China University of Technology");
}

消息轉(zhuǎn)發(fā)中的使用:
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
NSMethodSignature *signature = [super methodSignatureForSelector:selector];
if (!signature) {
signature = [target methodSignatureForSelector:selector];
}
return signature;
}

+ (BOOL)resolveInstanceMethod:(SEL)sel
{
      if (sel == @selector(foo)) {
      class_addMethod([self class], sel, (IMP)dynamicMethodIMP, "V@:");
      return YES;
      }
      return [super resolveInstanceMethod:sel];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
       NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
       if (!signature) {
            for (id target in self.allDelegates) {
                 if ((signature = [target methodSignatureForSelector:aSelector])) {
                      break;
                 }
            }
       }
       return signature;
}

- (void)forwardInvocation:(NSInvocation *)anInvocation
{
      for (id target in self.allDelegates) {
           if ([target respondsToSelector:anInvocation.selector]) {
                [anInvocation invokeWithTarget:target];
           }
      }
}

- (BOOL)respondsToSelector:(SEL)aSelector
{
      if ([super respondsToSelector:aSelector]) {
          return YES;
      }

      for (id target in self.allDelegates) {
           if ([target respondsToSelector:aSelector]) {
                return YES;
           }
      }
      return NO;
}

備注: allDelegate是存儲delegate的數(shù)組結(jié)構(gòu)忍抽。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末八孝,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子鸠项,更是在濱河造成了極大的恐慌干跛,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祟绊,死亡現(xiàn)場離奇詭異楼入,居然都是意外死亡哥捕,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門嘉熊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來遥赚,“玉大人,你說我怎么就攤上這事阐肤≠旆穑” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵孕惜,是天一觀的道長愧薛。 經(jīng)常有香客問我,道長衫画,這世上最難降的妖魔是什么毫炉? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮削罩,結(jié)果婚禮上瞄勾,老公的妹妹穿的比我還像新娘。我一直安慰自己鲸郊,他們只是感情好丰榴,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布货邓。 她就那樣靜靜地躺著秆撮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪换况。 梳的紋絲不亂的頭發(fā)上职辨,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天,我揣著相機與錄音戈二,去河邊找鬼舒裤。 笑死,一個胖子當著我的面吹牛觉吭,可吹牛的內(nèi)容都是我干的腾供。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鲜滩,長吁一口氣:“原來是場噩夢啊……” “哼伴鳖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起徙硅,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤榜聂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嗓蘑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體须肆,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡匿乃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了豌汇。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幢炸。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖瘤礁,靈堂內(nèi)的尸體忽然破棺而出阳懂,到底是詐尸還是另有隱情,我是刑警寧澤柜思,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布岩调,位于F島的核電站,受9級特大地震影響赡盘,放射性物質(zhì)發(fā)生泄漏号枕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一陨享、第九天 我趴在偏房一處隱蔽的房頂上張望葱淳。 院中可真熱鬧,春花似錦抛姑、人聲如沸赞厕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽皿桑。三九已至,卻和暖如春蔬啡,著一層夾襖步出監(jiān)牢的瞬間诲侮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工箱蟆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留沟绪,地道東北人。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓空猜,卻偏偏與公主長得像绽慈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子辈毯,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉坝疼,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,715評論 0 9
  • 哈哈哈哈,看見大家都在寫自己的學習總結(jié)漓摩,本猿在躊躇了三年后終于下定決心也寫一些東西裙士。 簡單直接,直入主題將是宗旨管毙!...
    大鵬鳥閱讀 571評論 4 0
  • 這篇讀書筆記主要介紹了Objective-C底層的一些東西腿椎,比如Objective-C對象模型桌硫、objc_msgS...
    C9090閱讀 823評論 0 2
  • 1.在開發(fā)的時候可以創(chuàng)建一個工具類,繼承自我們的AFN中的請求管理者啃炸,再控制器中真正發(fā)請求的代碼使用自己封裝的工具...
    紅樓那一場夢閱讀 3,502評論 2 3
  • UIWebView 什么是UIWebView UIWebView是iOS內(nèi)置的瀏覽器控件 系統(tǒng)自帶的Safari瀏...
    Skywang閱讀 722評論 2 6