2011-04-07 8 views
10

NSInvocationオブジェクトのsetSelectorメソッドを、invocationWithMethodSignatureで既に渡されているオブジェクトに呼び出す必要がある理由がわかりません。私たちは[SomeObject instanceMethodSignatureForSelector: someSelector];へと再び[invocation setSelector:someSelector];にセレクタを渡さNSInvocationクラスのsetSelectorメソッドの目的は何ですか?

SEL someSelector; 
NSMethodSignature *signature; 
NSInvocation *invocation; 

someSelector = @selector(sayHelloWithString:); 

//Here we use the selector to create the signature 
signature = [SomeObject instanceMethodSignatureForSelector:someSelector]; 
invocation = [NSInvocation invocationWithMethodSignature:signature]; 

//Here, we again set the same selector 
[invocation setSelector:someSelector]; 
[invocation setTarget:someObjectInstance]; 
[invocation setArgument:@"Loving C" atIndex:2]; 

お知らせ:私たちは、次の手順を実行しNSInvocationオブジェクトを作成するには

紛失しているものがありますか?

+1

+1 - すでに何百万回も質問されておらず、解読不能なインスタントメッセージの専門用語では書かれていない質問をここで見ることをお勧めします。 :-) –

+0

小さなポイント: 'signature = [SomeObject instanceMethodSignatureForSelector:someSelector];は' signature = [[SomeObject class] instanceMethodSignatureForSelector:someSelector];でなければなりません。または署名= [SomeObject methodSignatureForSelector:someSelector]; ' – Brynjar

答えて

8

シグネチャはセレクタではありません。セレクタはメッセージの名前です。シグネチャは、パラメータと戻り値を定義します。同じシグネチャを持つ多くのセレクタを持つことができ、その逆もあります。 NSMethodSignatureを見ると、-selectorメソッドがないことに気付くでしょう。シグネチャは特定のセレクタを持ちません。

は、同じセレクタ@selector(setLocation:)が、異なるシグネチャを有する以下

- (void)setLocation:(CGFloat)aLocation; 
- (void)setLocation:(MyLocation*)aLocation; 

を考えます。

- (void)setX:(CGFloat)x; 
- (void)setY:(CGFloat)y; 

これらのシグネチャは同じですが、セレクタは異なります。

Selectorsこれを理解するには、ObjCプログラミング言語が役立ちます。

+0

あなたが言っていることを得ている間に、言語に少し冗長性があるようです。セレクタを2回設定しています(署名に1回、呼び出しインスタンスでもう一度)。私は個人的に(IMHO)セレクタ(私の場合はsomeSelectorで定義されていました)をシグネチャから派生する方が効率的だと思います。 – haroldcampbell

+0

署名からセレクタを派生させることはできません。ターゲットに質問することによって、ターゲットとセレクタからシグネチャを派生させることができます(新しいメソッドとクラスは実行時に作成できますが、コンパイル時にはこれを決めることはできません)。あなたは+ invocationWithTarget:selector:arguments: 'ショートカットメソッドがあるかもしれません(私のチームには同様のものを追加するカテゴリがあります)。呼び出しているコードを呼び出すだけでは効率的ではありませんが、もう少し便利です。 –

3

メソッドシグネチャは、戻り値の型と、引数の数と型のみを定義します。セレクタ名には何も含まれていません。例えば、これらの方法の全ては、異なるセレクタを持つにもかかわらず、同じシグネチャを持つ:

-(void) foo:(NSString*)fooString; 
-(void) bar:(NSString*)barString; 
-(void) baz:(NSString*)bazString; 
0

は、これはサイドの答えのようなものですが、あなたは、次の操作を行うことができるという事実は、私はメソッド間の分離をよりよく理解する助け署名とセレクタ。 とUIPopoverControllerのdismissPopoverAnimated:

このコードは、のUIViewControllerのviewDidAppearのでビューコントローラ

NSMethodSignature *sig = nil; 
sig = [[self class] instanceMethodSignatureForSelector:@selector(viewDidAppear:)]; 
NSInvocation *myInvocation = nil; 
myInvocation = [NSInvocation invocationWithMethodSignature:sig]; 

[myInvocation setTarget:_somePopoverController]; 
[myInvocation setSelector:@selector(dismissPopoverAnimated:)]; 
BOOL animate = YES; 
[myInvocation setArgument:&animate atIndex:2]; 
[myInvocation invoke]; 

ですBOOL引数を取り、voidを返し、あなたは1つのセレクタを使用してメソッドシグネチャを作成することができますが、呼び出しを送る両方別のものに。

関連する問題