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:] + 1163
NSCharacterSet *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]);
How to find out who called a method?
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?
Xcode / Objective-c - How to find the callers of a given method programmatically
Not exactly an answer, but it might help. This methods will give you a printout of stack or of caller in debug area. You can modify them of course to use the values as you please.
Code is kind of 'stolen' but i have no reference to where from.
#define SHOW_STACK NSLog(@"%@",[NSThread callStackSymbols])
#define SHOW_CALLER \
do { \
NSArray *syms = [NSThread callStackSymbols]; \
if ([syms count] > 1) { \
NSLog(@"<%@ %p> %@ - caller: %@ ", [self class], self, NSStringFromSelector(_cmd),[syms objectAtIndex:1]); \
} else { \
NSLog(@"<%@ %p> %@", [self class], self, NSStringFromSelector(_cmd)); \
} \
} while(0)
EDIT: you would probably want something like this:
NSString *caller = nil;
NSArray *syms = [NSThread callStackSymbols];
if (syms.count > 1)
{
caller = syms[1];
}
if (caller.length)
{
NSLog(@"%s called by %@",
__PRETTY_FUNCTION__,
caller);
}
There is another Q&A here on SO you might find very useful.
Finding caller method from called
Although I definitely recommend against doing this (Pass a flag as you suggest yourself), here's how you would see one level up in your call stack:
NSLog(@"%@", [[NSThread callStackSymbols] objectAtIndex:1]);
How to get the caller's class Name in objective C while using inheritance?
No. Methods have no way of knowing from which other object's method they are being called. There's not even the concept of a caller's identity. Methods can be called from a C function where there is no caller object at all.
I need to know from which subclass this method was called.
That being said, you probably just want to know of which (derived) class an object is:
NSLog(@"My class: %@", NSStringFromClass([self class]));
2014 Addendum: There's a gnu extension __builtin_return_address
that might be used for this purpose. Mike Ash shows how to use it to extract a callers symbol name (see "Caller Inspection"). I still think that the whole approach is a bit fragile and should only be used for debugging.
Related Topics
iOS Keeping Old Launch Screen and App Icon After Update
Testing Corelocation on iPhone Simulator
How to Create a Delay in Swift
Swift 2: Call Can Throw, But It Is Not Marked with 'Try' and the Error Is Not Handled
Get Progress from Datataskwithurl in Swift
How to Overload an Assignment Operator in Swift
iOS Universal Device App with Spritekit, How to Scale Nodes for All Views
Error When Adding Input View to Textfield iOS 8
Secitemadd and Secitemcopymatching Returns Error Code -34018 (Errsecmissingentitlement)
How to Display .Svg Image Using Swift
How to Click a Button Behind a Transparent Uiview
Failed to Read Values in Cfprefsplistsource iOS 10
Capturing and Storing a Picture Taken with the Camera into a Local Database/Phonegap/Cordova/Ios
Receiver (<Viewcontroller>) Has No Segue with Identifier 'Addsegue'