Objective-C class -> string like: [NSArray className] -> @"NSArray"
Asked Answered
S

3

131

I am trying to get a string name of a class from the class object itself.

// For instance
[NSArray className]; // @"NSArray"

I have found object_getClassName(id obj) but that requires an instance be passed to it, and in my case that is needless work.

So how can I get a string from a class object, and not an instance?

Speaks answered 25/2, 2010 at 6:1 Comment(0)
T
314
NSString *name = NSStringFromClass ([NSArray class]);

You can even go back the other way:

Class arrayClass = NSClassFromString (name);
id anInstance = [[arrayClass alloc] init];
Trierarch answered 25/2, 2010 at 6:4 Comment(8)
Thanks! How is NSStringFromClass implemented? Is it more performant to store the class name in a static NSString variable?Obaza
@MattDiPasquale: All class names are stored somewhere in the Objective-C runtime (the internals of the runtime are mostly hidden from the application and exposed only through a few API functions). Each class object (e.g. [NSArray class]) is actually a struct. The struct contains a lot of information about the class, including its name, the methods it implements, the superclass, etc. NSStringFromClass just pulls the name of the class from this struct and converts it to an NSString. Don't store the class name in a static NSString, it won't offer any performance advantage.Trierarch
@MattDiPasquale: NSClassFromString works a bit differently. Since all of the class names exist somewhere in the Objective-C runtime, NSClassFromString takes the string and explores the list of classes maintained by the runtime looking for the class that has the given name. If it finds it, it returns it, otherwise it returns Nil.Trierarch
@MattDiPasquale: "How is NSStringFromClass implemented?" if you really want to know, it probably uses class_getName() in the runtime, which returns a C stringRamburt
Out of curiosity, why does this not work? NSString *name = [NSArray className];Chuffy
@AlexZavatone: className is a method added by the scripting extensions which is only available on Mac OS X, even then it is finicky in how it works because it is not fully documented (or at least it wasn't the last time I checked). NSStringFromClass() is the correct way to go about it.Trierarch
To call a static method, will [arrayClass staticMethod] work?Effuse
@Vijay: Yes, invoking [arrayClass classMethod] will invoke a class method, just like doing [[someArray class] classMethod].Trierarch
L
2

Here's a different way to do it with slightly less typing:

NSString *name = [NSArray description];
Leboeuf answered 28/12, 2012 at 22:56 Comment(3)
That's not guaranteed to do what is requested. That method is commonly overidden to provide a description of the object and the data it contains.Speaks
I know it is overridden as an INSTANCE method but how often is the +description CLASS METHOD overridden? In any event it's worth considering if not for every class ... I don't think a downgrade was called for.Leboeuf
@SherwinZadeh: I think in practice, you are unlikely to find classes that have overridden +description, however, in theory, this is not the purpose for +description, and so this method is fragile for determining class names.Trierarch
S
2

Consider this alternative:

const char *name = class_getName(cls);

It's much faster, since it doesn't have to alloc NSString object and convert ASCII to whatever NSString representation is. That's how NSStringFromClass() is implemented.

Sirdar answered 26/9, 2017 at 18:11 Comment(1)
This was useful for me, but needed to add #import <objc/runtime.h> at the top of the file.Stimulative

© 2022 - 2024 — McMap. All rights reserved.