Cocoa API解説(macOS/iOS)

iOS , Mac アプリケーション開発のために使われる主要フレームワークの日本語情報です。

目次

NSInvocationクラス

INDEX>Foundation>

apple(mac)
apple(iOS)

解説

呼び出しオブジェクト
メソッド名、引数などをセットしてメソッドを呼び出すオブジェクト
デフォルトでは引数をretainしません。
アーカイビングは非サポートです。

継承 NSObject
準拠 NSObject (NSObject)
フレームワーク /System/Library/Frameworks/Foundation.framework
使用可能 Mac OS X v10.0以降
iOS 2.0以降
定義 NSInvocation.h

概要

タイマーや分散オブジェクトでObjective-Cのメッセージを送信するために使われます。
ブロックからのメソッド呼び出しにも使用できます。

デフォルトでは含まれる引数の保持は行いませんのでretainArgumentsメソッドを呼び出す必要があります。

このクラスはNSCodingプロトコルではなく、NSPortCoderプロトコルのみをサポートしています。

起動オブジェクトの作成

メソッドシグネチャーから起動オブジェクトを作成するには(+ invocationWithMethodSignature)メソッドを使用します。

起動オブジェクトの設定

セレクタを取得するには(– selector)メソッドを、セットするには(– setSelector)メソッドを使用します。
ターゲットを取得するには(– target)メソッドを、セットするには(– setTarget)メソッドを使用します。
返り値を取得するには(– getReturnValue)メソッドを、セットするには(– setReturnValue)メソッドを使用します。

引数を取得するには(– getArgument:atIndex)メソッドを、セットするには(– setArgument:atIndex)メソッドを使用します。引数のタイプは@encode(@)で表せます。タイプの一例を下記にあげます。
オブジェクト(NSString *など) @
オブジェクトのポインタ(NSString **など) ^@
BOOL c
int i
float f
SEL :
NSInteger i

引数の保持を行うかどうかを取得するには(– retainArguments)メソッドを使用します。セットするには(– argumentsRetained)メソッドを使用します。

起動の処理

起動オブジェクトを起動するには(– invoke)メソッドを使用します。ターゲットを指定して起動するには(– invokeWithTarget)メソッドを使用します。

メソッドシグネチャーの取得

起動オブジェクトのメソッドシグネチャを取得するには(– methodSignature)メソッドを使用します。メソッドシグネチャから引数の情報を得ることができます。


状況に応じて呼び出すメソッドを変更するサンプル。
method001を呼び出すとtestSelector1とtestSelector2が交互に呼び出されます。

NSTimer *timer=nil;
NSInvocation * invocation ;//起動オブジェクト

-(NSInteger) testSelector1:(NSString *)string
{
    NSLog(@"...call %s",__FUNCTION__);
    
	//やっぱり testSelector2:メソッドを呼び出すことにする
	[invocation setSelector:@selector( testSelector2: )];
	
    
    //タイマーで1秒後にinvocationオブジェクを起動
	timer = [NSTimer scheduledTimerWithTimeInterval:1
                                         invocation:	invocation
                                            repeats:NO];
	return 1;
}
-(NSInteger) testSelector2:(NSString *)string
{
    NSLog(@"...call %s",__FUNCTION__);
	
	//やっぱり testSelector1:メソッドを呼び出すことにする
	[invocation setSelector:@selector( testSelector1: )];
	
	//タイマーで1秒後にinvocationオブジェクを起動
	timer = [NSTimer scheduledTimerWithTimeInterval:1
                                         invocation:	invocation
                                            repeats:NO];
	return 2;
}

-(void)method001
{
    //呼び出すメソッドをコロコロ変えるサンプル
    NSMethodSignature * aSignature ;//メソッドシグネチャ    
    SEL aSelector  = @selector( testSelector1: );//セレクタをセット	
    aSignature = [ self methodSignatureForSelector:aSelector ];//セレクタのシグネチャをセット
	
    invocation = [ NSInvocation invocationWithMethodSignature:aSignature ];//起動オブジェクトをセット
	//引数の保持
    NSLog(@"argumentsRetained %@",([invocation argumentsRetained])?@"YES":@"NO");
    [invocation retainArguments];
	NSLog(@"argumentsRetained %@",([invocation argumentsRetained])?@"YES":@"NO");
    
	NSLog(@"%@",[aSignature description]);
	
	//起動オブジェクトにターゲットと引数をセットする
    [ invocation setTarget: self ];//ターゲットはself
    [ invocation setSelector: aSelector ];//セレクタをセット
    [ invocation invoke ];//起動する
  
}

ブロック内からメソッドを呼び出すサンプル

#pragma mark NSInvocation
NSTimer *timer=nil;
NSInvocation * invocation ;//起動オブジェクト
-(void) testSelector002:(NSString *)string
{
    NSLog(@"...call %s %@",__FUNCTION__,string);
    
}
-(void)method002
{
    SEL aSelector  = @selector( testSelector002: );//セレクタをセット
    NSMethodSignature *aSignature = [ self methodSignatureForSelector:aSelector ];//セレクタのシグネチャをセット
	
    NSInvocation *aInvocation = [ NSInvocation invocationWithMethodSignature:aSignature ];//起動オブジェクトをセット
	
	//起動オブジェクトにターゲットと引数をセットする
    [ aInvocation setTarget: self ];//ターゲットはself
    [ aInvocation setSelector: aSelector ];//セレクタをセット

    
    NSArray *anArray = 
    [[NSArray alloc] initWithObjects:   @"aaa",@"bbb",@"ccc",
     @"ddd",@"eee",@"fff",
     @"ggg",@"hhh",@"iii",nil];
    
    [anArray enumerateObjectsWithOptions:NSEnumerationConcurrent //並列 
                                        //NSEnumerationReverse  //逆向き
                              usingBlock:^(id s,NSUInteger idx,BOOL *stop){

                                  //起動
                                  //配列の要素を引数としてメソッドを起動する
                                  [ aInvocation setArgument:&s atIndex:2];
                                        //-(void) testSelector002:(NSString *)stringの引数
                                        //0 self  通常隠されている
                                        //1 _cmd  通常隠されている
                                        //2 (NSString *)string
                                  [ aInvocation invoke ];//起動する

                                  
                              }]; 
    //=>...call -[OOOAppDelegate testSelector002:] aaa
    //=>...call -[OOOAppDelegate testSelector002:] bbb
    //=>...call -[OOOAppDelegate testSelector002:] ccc
    //=>...call -[OOOAppDelegate testSelector002:] ddd
    //=>...call -[OOOAppDelegate testSelector002:] eee
    //=>...call -[OOOAppDelegate testSelector002:] fff
    //=>...call -[OOOAppDelegate testSelector002:] ggg
    //=>...call -[OOOAppDelegate testSelector002:] hhh
    //=>...call -[OOOAppDelegate testSelector002:] iii

}

引数を調べるサンプル

#pragma mark NSInvocation getArgumentTypeAtIndex:
-(void) testSelector003:(NSString *)string
{
    NSLog(@"...call %s %@",__FUNCTION__,string);
    
}
-(void)method003
{
    SEL aSelector  = @selector( testSelector003: );//セレクタをセット
    NSMethodSignature *aSignature = [ self methodSignatureForSelector:aSelector ];//セレクタのシグネチャをセット
	
    NSInvocation *anInvocation = [ NSInvocation invocationWithMethodSignature:aSignature ];//起動オブジェクトをセット
	
	//起動オブジェクトにターゲットと引数をセットする
    [ anInvocation setTarget: self ];//ターゲットはself
    [ anInvocation setSelector: aSelector ];//セレクタをセット
    
    NSMethodSignature *methodSignature = [anInvocation methodSignature];
    NSInteger counter = [methodSignature numberOfArguments];
    
    for (NSInteger i=0; i<counter; i++) {
        const char *argInfo = [methodSignature getArgumentTypeAtIndex:i];
        NSString *str = [NSString stringWithCString:argInfo encoding:NSASCIIStringEncoding];        
        NSLog(@"%s %@",__FUNCTION__,str);
        
    }
    //-(void) testSelector003:(NSString *)stringについての情報
    //=>-[OOOAppDelegate method001] @ //引数0  self @オブジェクト
    //=>-[OOOAppDelegate method001] : //引数1  _cmd       :セレクタ
    //=>-[OOOAppDelegate method001] @ //引数2  (NSString *) @オブジェクト
    //@encode(@)などでタイプが表せる
    //NSString *  @
    //NSString ** ^@
    //BOOL        c
    //int         i
    //float       f
    //SEL         :
    //NSInteger   i
}

適合するプロトコル

メソッド

起動オブジェクトの作成
OS X iOS 説明
+ invocationWithMethodSignature 10.0 2.0 起動オブジェクトを作成して返します。
呼び出しオブジェクトの設定
– setSelector 10.0 2.0
– selector 10.0 2.0
– setTarget 10.0 2.0
– target 10.0 2.0
– setArgument:atIndex 10.0 2.0
– getArgument:atIndex 10.0 2.0
– argumentsRetained 10.0 2.0
– retainArguments 10.0 2.0
– setReturnValue 10.0 2.0
– getReturnValue 10.0 2.0
呼び出しオブジェクトの発信
– invoke 10.0 2.0 起動します。
– invokeWithTarget 10.0 2.0
メソッドシグネチャの取得
– methodSignature 10.0 2.0