Objective-C find caller of method
StackI hope that this helps:
NSString *sourceString = [[NSThread callStackSymbols] objectAtIndex:1];// Example: 1 UIKit 0x00540c89 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1163NSCharacterSet *separatorSet = [NSCharacterSet characterSetWithCharactersInString:@" -[]+?.,"];NSMutableArray *array = [NSMutableArray arrayWithArray:[sourceString componentsSeparatedByCharactersInSet:separatorSet]];[array removeObject:@""];NSLog(@"Stack = %@", [array objectAtIndex:0]);NSLog(@"Framework = %@", [array objectAtIndex:1]);NSLog(@"Memory address = %@", [array objectAtIndex:2]);NSLog(@"Class caller = %@", [array objectAtIndex:3]);NSLog(@"Function caller = %@", [array objectAtIndex:4]);
In fully optimized code, there is no 100% surefire way to determine the caller to a certain method. The compiler may employ a tail call optimization whereas the compiler effectively re-uses the caller's stack frame for the callee.
To see an example of this, set a breakpoint on any given method using gdb and look at the backtrace. Note that you don't see objc_msgSend() before every method call. That is because objc_msgSend() does a tail call to each method's implementation.
While you could compile your application non-optimized, you would need non-optimized versions of all of the system libraries to avoid just this one problem.
And this is just but one problem; in effect, you are asking "how do I re-invent CrashTracer or gdb?". A very hard problem upon which careers are made. Unless you want "debugging tools" to be your career, I would recommend against going down this road.
What question are you really trying to answer?
Using answer provided by intropedro, I came up with this:
#define CALL_ORIGIN NSLog(@"Origin: [%@]", [[[[NSThread callStackSymbols] objectAtIndex:1] componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"[]"]] objectAtIndex:1])
which will simply return me Original class and function:
2014-02-04 16:49:25.384 testApp[29042:70b] Origin: [LCallView addDataToMapView]
p.s. - if function is called using performSelector, result will be:
Origin: [NSObject performSelector:withObject:]