4

Not the function calling the NSLog or Dlog but function that call that function.

I created a class

+(void) computeTime:(void (^)())block
{
    NSDate * currentTime = [NSDate date];
    block();
    DLog ("Time Running is: %f", [[NSDate date] timeIntervalSinceDate:currentTime);
}

So everytime there is an operation whose time I want to measure I will put that in a block instead.

and do [Tools computeTime:^{//operation}];

However, I want to know the function that call that computeTime. How do I do so?

user4951
  • 32,206
  • 53
  • 172
  • 282

2 Answers2

7

Another possible answer for someone searching for the OP's original question and adding to Kevin's first suggestion to use the call stack.

If you're looking for what called a function (method), consider the following:

 NSArray *callStack = [NSThread callStackSymbols];
 // Top of the stack. Current method
 NSLog(@"Current method: %@", [callStack objectAtIndex:0]);
 // Called by
 NSLog(@"called by: %@", [callStack objectAtIndex:1]);

It is possible that the stack item looked for is further into stackArray.

Hope this helps find a bug quicker.

JNK
  • 1,753
  • 8
  • 25
  • 37
David
  • 3,285
  • 1
  • 37
  • 54
7

Two options:

The first is to abuse +[NSThread callStackSymbols] to get an array of all the symbols in the call stack and pull out the one you want. I suspect this is going to be relatively slow.

The second is to use a macro. The C preprocessor provides a nice macro called __PRETTY_FUNCTION__ which contains the name of the function all nicely formatted, and it works well for Obj-C methods as well. Instead of [Tools computeTime:^{/*operation*/}] you can either use something like [Tools computeTimeWithName:__PRETTY_FUNCTION__ block:^{/*operation*/}] or you could wrap it all up in your own macro so you can say TOOLS_COMPUTE_TIME(^{/*operation*/}):

#define TOOLS_COMPUTE_TIME(...) [Tools computeTimeWithName:__PRETTY_FUNCTION__ block:(__VA_ARGS__)]

Note, I've used a varargs-style macro because the C Preprocessor doesn't understand obj-c syntax very well, so any commas inside your block will be interpreted as separate arguments to the macro. If I defined it using TOOLS_COMPUTE_TIME(op) then the compiler would complain that the macro only takes 1 argument but it was given multiple. By using varargs the compiler doesn't care how many arguments you give it, and it will pass them all on to the __VA_ARGS__ token.

Lily Ballard
  • 182,031
  • 33
  • 381
  • 347