NSInvocation簡單總結


(1)用法

 NSInvocation是調用函數的另一種方式,它將調用者,函數名,參數封裝到一個對象,然后通過一個invoke函數來執行被調用的函數,其思想就是命令者模式,將請求封裝成對象。

例如,有這樣一個類:

@implementation CA

-(int)AddA:(int)a andB:(int)b

{   

      return a + b;

}

@end

 

一般調用函數的方式是:

CA *ca = [CA new];

int result = [ca AddA:2 andB:3];

 

或者用performSelector,但是后者只能有一個參數,所以對於有多個參數的情況,就可以用NSInvocation來調用。

示例代碼:

 

    CA *ca = [CA new];

    NSMethodSignature *sig= [[CA class] instanceMethodSignatureForSelector:@selector(AddA:andB:)]; //根據selector得到一個簽名對象

    NSInvocation *invocation=[NSInvocation invocationWithMethodSignature:sig];//根據該簽名對象創建一個NSInvocation對象

    invocation.target = ca;//指定調用函數的對象

    invocation.selector = @selector(AddA:andB:);//指定要調用的函數名

    int a = 20;

    int b = 30;

    

    [invocation setArgument:&a atIndex:2];//指定參數,以指針方式,並且第一個參數的起始index是2,因為index為1,2的分別是self和selector

    [invocation setArgument:&b atIndex:3];

    [invocation retainArguments];//因為NSInvocation不會自己去retain參數,因此需要用戶去retain,當然本例中其實沒必要

      [invocation invoke];

 
    //獲取返回值的過程略有點復雜,需要根據起類型長度分配空間,然后轉為對象

    //如果是int,BOOL等簡單類型,返回的對象是NSNumber

    //如果是其他類型的對象,返回的對象是NSValue

     //判斷返回值類型,用strcmp(returnType, @encode(NSInteger))

 

    const char *returnType = sig.methodReturnType;

    id returnValue;

    NSUInteger length = [sig methodReturnLength];

    void *buffer = (void *)malloc(length);

    [invocation getReturnValue:buffer];

    returnValue = [NSNumber numberWithInteger:*((NSInteger*)buffer)];//int的情況

    //returnValue = [NSNumber numberWithBool:*((BOOL*)buffer)]; //bool 的情況

      //returnValue = [NSValue valueWithBytes:buffer objCType:returnType];// 其他類型的情況

    

    int result = [returnValue intValue];

    NSLog(@"result=%d",result);

  

 

(2) 用到NSInvocation的一些場合

    [NSTimer scheduledTimerWithTimeInterval:0.1 invocation:invocation repeats:YES]

 

    NSInvocationOperation //它是NSOperation的派生類,用NSInvoation來初始化

 

    (void)forwardInvocation:(NSInvocation *)anInvocation

    這個函數與forwardTargetWithSelector類似,當某個對象收到一個selector消息,但該對象沒有實現該selector,且實現forwardInvocation,那么系統會構造一個NSInvocation對象,並調用forwardInvocation,這樣在函數里面,用戶就可以用[invocation invokeWithTarget:friend];來讓另一個對象來執行這個selector.

      要實現這個函數,還必須實現methodSignatureForSelector,因為這個anInvocation是系統構造的,構造這個對象需要有簽名對象,這個對象必須由用戶提供。所以這個函數用起來比forwardingTargetForSelector麻煩 

    另外,由於使用forwardInvocation可以使得一個對象將它沒有實現的方法轉發給其他對象,因此可以變相的實現多繼承。

 

參考鏈接:http://www.cnblogs.com/pengyingh/articles/2359199.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM