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?

Jonathan Sterling
  • 18,320
  • 12
  • 67
  • 79
Alex Wayne
  • 178,991
  • 47
  • 309
  • 337

3 Answers3

312
NSString *name = NSStringFromClass ([NSArray class]);

You can even go back the other way:

Class arrayClass = NSClassFromString (name);
id anInstance = [[arrayClass alloc] init];
dreamlax
  • 93,976
  • 29
  • 161
  • 209
  • Thanks! How is `NSStringFromClass` implemented? Is it more performant to store the class name in a `static NSString` variable? – ma11hew28 Apr 10 '11 at 18:00
  • 13
    @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. – dreamlax Apr 10 '11 at 23:43
  • 3
    @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`. – dreamlax Apr 10 '11 at 23:47
  • 2
    @MattDiPasquale: "How is NSStringFromClass implemented?" if you really want to know, it probably uses `class_getName()` in the runtime, which returns a C string – user102008 Jul 22 '11 at 21:56
  • Out of curiosity, why does this not work? NSString *name = [NSArray className]; – Alex Zavatone Nov 12 '12 at 19:01
  • 2
    @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. – dreamlax Nov 12 '12 at 23:23
  • To call a static method, will [arrayClass staticMethod] work? – vijayst Dec 09 '14 at 22:27
  • @Vijay: Yes, invoking `[arrayClass classMethod]` will invoke a class method, just like doing `[[someArray class] classMethod]`. – dreamlax Dec 10 '14 at 07:46
2

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

NSString *name = [NSArray description];
Sherwin Zadeh
  • 1,339
  • 15
  • 17
  • 7
    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. – Alex Wayne Dec 28 '12 at 23:07
  • 3
    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. – Sherwin Zadeh Dec 31 '12 at 00:01
  • 3
    @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. – dreamlax Mar 29 '16 at 12:25
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.

wonder.mice
  • 7,227
  • 3
  • 36
  • 39