Reputation: 2491
I have really simple example, but I can't understand how I could get information about the method that call selector inside it. For example:
-(void)methodOne {
[self performSelector:@selector(methodTwo:)];
}
-(void)methodTwo:(id)sender {
//How to know which method performed selector???
}
I think this example is pretty simple, I just need to understand this, again, the question is, how could I know from methodTwo: which method perform selector, so from which method I called methodTwo:.
Thanks in advance!
Upvotes: 2
Views: 1545
Reputation: 6886
You can't know from the second method which method called it, at least not without going through the call stack (see NSThread
) but you can pass this information from the first method like this:
- (void)doSomething {
[self doSomethingElseWithCallee: NSStringFromSelector(_cmd) andSender: self];
}
- (void)doSomethingElseWithCallee: (NSString *)selector andSender: (id)sender] {
// Do something…
}
Or you could just pass the selector (of type SEL
) right away, instead of a string:
- (void)doSomething {
[self doSomethingElseWithCallee: _cmd andSender: self];
}
- (void)doSomethingElseWithCallee: (SEL)selector andSender: (id)sender] {
// Do something…
}
By the way, _cmd
is a special argument that the Objective-C runtime passes to your method, along with self
(the current object). They're not included in your method signature, but the compiler does all the work for you. ;-)
All hail the Objective-C language! :-p
Upvotes: 1
Reputation: 21249
If you do want to know which method calls your methodTwo
, you can look at call stack. Look at this ...
-(void)methodOne {
[self performSelector:@selector(methodTwo:)];
}
-(void)methodTwo:(id)sender {
NSLog( @"%@", [NSThread callStackSymbols][1]);
NSLog( @"%@", [NSThread callStackSymbols][2]);
}
... and the log output (simplified) is ...
0x014ef671 -[NSObject performSelector:] + 62
0x00002307 -[CMAppDelegate methodOne] + 55
... callStackSymbols
returns NSArray
with call stack symbols, so, you can look at index 1 to get method which did you call your method. As you can see, there's NSObject
's performSelector
and it's because you called methodTwo
via performSelector
. If you change your methodOne
in this way ...
-(void)methodOne {
[self methodTwo:nil];
}
... the output is ...
0x000022fe -[CMAppDelegate methodOne] + 62
0x000025d6 -[CMAppDelegate application:didFinishLaunchingWithOptions:] + 374
... that's it. Your question is answered, but I dunno why do you want this. You probably don't want to know which method exactly did call your method, but which object initiated this call chain. An example is button - you can have one method to handle more buttons and there's sender
argument to distinguish between these buttons as @stavash pointed out.
Upvotes: 6
Reputation: 14314
Try using performSelector:withObject:
-(void)methodOne {
NSString *identifierStr = @"methodOne";
[self performSelector:@selector(methodTwo:) withObject:identifierStr];
}
-(void)methodTwo:(NSString *)senderIdentifierStr {
NSLog(@"Sent by %@",senderIdentifierStr);
}
Upvotes: 2