8

I have a base class called BaseClass . Many classes derived from the BaseClass namely SubClass1 , SubClass2 and SubClass3.

@interface  BaseClass: NSObject{
}
-(void)configure;
@end;

@implementation
-(void)configure{
NSLog(@"This needs to log from which sub class this method was called");
}
@end;

The configure method can be called by creating instances of the subclasses or within the implementations of them.

I need to know from which subclass this method was called.

Is this possible?

RK-
  • 12,099
  • 23
  • 89
  • 155
  • Do you require the type of the class that is having the method called on it (in which case see my answer below), the instance that is having the method called on it (which is `self`), or the type or instance of the caller (which can't be done without passing it explicitly, ie implementing `-(void)configure:(id)sender`)? – Vic Smith Aug 08 '12 at 13:24
  • In that case check out my revised answer. – Vic Smith Aug 08 '12 at 13:35

4 Answers4

13

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.

Nikolai Ruhe
  • 81,520
  • 17
  • 180
  • 200
6

The accepted answer is not correct.

NSArray *stack = [NSThread callStackSymbols];
NSString *methodThatDidLogging = [stack objectAtIndex:1];

You can easily parse this string to get the class and method name of the caller.

I use this in my custom logger to print out the class and method that is logging a message

Cheers

deleted_user
  • 3,817
  • 1
  • 18
  • 27
  • 3
    I did not mention this approach in my answer as it seems too fragile for production code. It uses the `backtrace_symbols` API which seems to be made for debugging and error handling. Also, it might depend upon debugging symbols being present for stack unwinding. It is probably very slow. – Nikolai Ruhe Aug 08 '12 at 22:17
  • OP never specified that that this was for production code. – Wowfunhappy Jun 27 '22 at 22:37
2

You can also use:

const char* class_getName(Class cls)

defined in <objc/runtime.h>

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
1

The answer depends on whether you want the class or instance, and whether it is the sender or the receiver of the message you are interested in.

For the class of the receiver, you can use the -class method (declared in NSObject), ie

-(void)configure
{
    NSLog(@"This logs from which sub class this method was called");
    NSLog(@"Class of this object is %@", [self class]);
}

The receiver instance is just self of course. If is the sender you are interested in, you can't get this automatically, but can pass it as a argument. So you'd have something like

-(void)configure:(id)sender
{
    NSLog(@"This logs from which sub class this method was called");
    NSLog(@"Class of object that called this method is %@", [sender class]);
}
Vic Smith
  • 3,477
  • 1
  • 18
  • 29
  • This does not print the caller's class, as requested in the question. – Nikolai Ruhe Aug 08 '12 at 13:14
  • @Krishnan said: "I need to know from which subclass this method was called." This can be interpreted either as getting the name of the type, or the actual instance that called it, I had assuemed to the former. Which do you need @Krishnan? – Vic Smith Aug 08 '12 at 13:16