Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the caller's class Name in objective C while using inheritance?

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?

like image 348
RK- Avatar asked Aug 08 '12 13:08

RK-


4 Answers

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.

like image 100
Nikolai Ruhe Avatar answered Nov 11 '22 08:11

Nikolai Ruhe


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

like image 27
deleted_user Avatar answered Nov 11 '22 08:11

deleted_user


You can also use:

const char* class_getName(Class cls)

defined in <objc/runtime.h>

like image 2
Thiagarajan Hariharan Avatar answered Nov 11 '22 07:11

Thiagarajan Hariharan


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]);
}
like image 1
Vic Smith Avatar answered Nov 11 '22 08:11

Vic Smith