NSInvocationクラス
解説
呼び出しオブジェクト
メソッド名、引数などをセットしてメソッドを呼び出すオブジェクト
デフォルトでは引数を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 |