如何找出谁叫一个方法?
例子:当我的方法-fooBar被调用时,我想让它login控制台,其他类调用它的其他方法。
现在,我只知道如何loggingfooBar本身的方法名称,它的类是这样的:
_cmd [self class]
这有可能弄清楚吗?
在完全优化的代码中,没有100%确定的方法来确定调用者使用某种方法。 编译器可以使用尾部调用优化,而编译器有效地重新使用调用者的被调用者的栈帧。
要看到这个例子,使用gdb在任何给定的方法上设置一个断点,并看看回溯。 请注意,在每次方法调用之前,都没有看到objc_msgSend()。 这是因为objc_msgSend()会对每个方法的实现进行尾部调用。
虽然您可以编译未优化的应用程序,但您需要所有系统库的非优化版本才能避免这个问题。
这只是一个问题, 实际上,你是在问“我该如何重新发明CrashTracer或gdb?”。 一个非常困难的问题,在哪个职业上。 除非你想“debugging工具”成为你的职业,否则我会build议不要走这条路。
你真的想回答什么问题?
这个怎么样:
NSString *sourceString = [[NSThread callStackSymbols] objectAtIndex:1]; NSCharacterSet *separatorSet = [NSCharacterSet characterSetWithCharactersInString:@" -[]+?.,"]; NSMutableArray *array = [NSMutableArray arrayWithArray:[sourceString componentsSeparatedByCharactersInSet:separatorSet]]; [array removeObject:@""]; NSLog(@"Class caller = %@", [array objectAtIndex:3]); NSLog(@"Method caller = %@", [array objectAtIndex:4]);
感谢原作者, intropedro 。
一般情况下不可能实际上没有走栈。 甚至没有保证另一个对象发送调用该方法的消息。 例如,它可以从信号处理程序中的块中调用。
参见回溯(3) 。
用户下面的方法
要显示方法的传递索引,如果要显示方法的完整堆栈,则传递-1
+(void) methodAtIndex:(int)index{ void* callstack[128]; int frames = backtrace(callstack, 128); char** strs = backtrace_symbols(callstack, frames); if (index == -1) { for (int i = 0; i < frames; ++i) { printf("%s\n", strs[i]); } } else { if (index < frames) { printf("%s\n", strs[index]); } } free(strs); }
这些信息可以使用DTrace
获得。
创build一个macros,将__FUNCTION__
添加到该函数调用的函数名称中。 然后这个macros将使用额外的char *参数来调用你的函数。
NSLog(@"Show stack trace: %@", [NSThread callStackSymbols]);
我试图抓住谁,如何和何时改变窗户的大小,并做了一些手工:
- (void)logWindowWidth:(NSString *)whoCalls { NSLog(@"%@", whoCalls); NSLog(@"self.window.size.width %f", self.window.size.width); } -(void)someMethod { [self logWindowWidth:@"someMethod - before"]; ... [self logWindowWidth:@"someMethod - after"]; } -(void)anotherMethod { [self logWindowWidth:@"anotherMethod - before"]; ... [self logWindowWidth:@"anotherMethod - after"]; }