2

非常に簡単な例がありますが、その中のセレクターを呼び出すメソッドに関する情報を取得する方法がわかりません。例えば:

-(void)methodOne {
   [self performSelector:@selector(methodTwo:)];
}
-(void)methodTwo:(id)sender {
   //How to know which method performed selector???
}

この例は非常に単純だと思います。これを理解する必要があります。繰り返しになりますが、問題は、methodTwo:どのメソッドがセレクターを実行するかをどのように知ることができるかということです。

前もって感謝します!

4

3 に答える 3

6

どのメソッドが自分のを呼び出すかを知りたい場合はmethodTwo、呼び出しスタックを調べることができます。これを見て...

-(void)methodOne {
  [self performSelector:@selector(methodTwo:)];
}

-(void)methodTwo:(id)sender {
  NSLog( @"%@", [NSThread callStackSymbols][1]);
  NSLog( @"%@", [NSThread callStackSymbols][2]);
}

...そしてログ出力(簡略化)は...

0x014ef671 -[NSObject performSelector:] + 62
0x00002307 -[CMAppDelegate methodOne] + 55

...コールスタックシンボルでcallStackSymbols返さNSArrayれるので、インデックス1を調べて、メソッドを呼び出したメソッドを取得できます。ご覧のとおり、がありますNSObject。これは、を介しperformSelectorて呼び出したためです。このように変更すると...methodTwoperformSelectormethodOne

-(void)methodOne {
  [self methodTwo:nil];
}

...出力は...

0x000022fe -[CMAppDelegate methodOne] + 62
0x000025d6 -[CMAppDelegate application:didFinishLaunchingWithOptions:] + 374

... それでおしまい。あなたの質問は答えられますが、なぜあなたはこれが欲しいのか分かりません。どのメソッドがメソッドを正確に呼び出したかを知りたくないかもしれませんが、どのオブジェクトがこの呼び出しチェーンを開始したかを知りたくありません。例はボタンです-より多くのボタンを処理する1つの方法がありsender、@stavashが指摘したようにこれらのボタンを区別するための引数があります。

于 2012-07-21T09:09:04.523 に答える
2

PerformSelector:withObjectを使用してみてください:

-(void)methodOne {
   NSString *identifierStr = @"methodOne";
   [self performSelector:@selector(methodTwo:) withObject:identifierStr];
}
-(void)methodTwo:(NSString *)senderIdentifierStr {
   NSLog(@"Sent by %@",senderIdentifierStr);
}
于 2012-07-21T08:50:03.513 に答える
1

2番目のメソッドからは、少なくとも呼び出しスタック(を参照)を経由せずに、どのメソッドがそれを呼び出したかを知ることはできませんが、次のNSThreadように最初のメソッドからこの情報を渡すことができます。

- (void)doSomething {
    [self doSomethingElseWithCallee: NSStringFromSelector(_cmd) andSender: self];
}

- (void)doSomethingElseWithCallee: (NSString *)selector andSender: (id)sender] {
    // Do something…
}

SELまたは、文字列の代わりに、(タイプの)セレクターをすぐに渡すこともできます。

- (void)doSomething {
    [self doSomethingElseWithCallee: _cmd andSender: self];
}

- (void)doSomethingElseWithCallee: (SEL)selector andSender: (id)sender] {
    // Do something…
}

ちなみに、は、Objective-Cランタイムが(現在のオブジェクト)_cmdとともにメソッドに渡す特別な引数です。selfこれらはメソッドシグネチャには含まれていませんが、コンパイラがすべての作業を代行します。;-)

すべてがObjective-C言語を歓迎します!:-p

于 2012-07-21T09:10:02.133 に答える