Objective-C类->这样的字符串:[NSArray className]-> @“ NSArray”


128

我试图从类对象本身获取一个类的字符串名称。

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

我已经找到了,object_getClassName(id obj)但这需要将实例传递给它,在我来说,这是不必要的工作。

那么如何从类对象而不是实例中获取字符串?

Answers:


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

您甚至可以返回另一种方式:

Class arrayClass = NSClassFromString (name);
id anInstance = [[arrayClass alloc] init];

谢谢!如何NSStringFromClass实施?将类名存储在static NSString变量中性能更高吗?
ma11hew28 2011年

13
@MattDiPasquale:所有类名都存储在Objective-C运行时中的某个位置(运行时的内部大部分对应用程序隐藏,并且仅通过一些API函数公开)。每个类对象(例如[NSArray class])实际上是一个struct。在struct包含了很多关于该类,包括其名称,方法它实现,超类等NSStringFromClass只是拉动类的名称从这个struct并将其转换为一个NSString。不要将类名称存储在中static NSString,这不会提供任何性能优势。
dreamlax 2011年

3
@MattDiPasquale:NSClassFromString工作方式有所不同。由于所有类名都存在于Objective-C运行时中的某个地方,因此请NSClassFromString获取字符串并浏览由运行时维护的类列表,以查找具有给定名称的类。如果找到它,则返回它,否则返回Nil
dreamlax 2011年

2
@MattDiPasquale:“如何实现NSStringFromClass?” 如果您真的想知道,它可能会class_getName()在运行时中使用,它返回一个C字符串
user102008 2011年

2
@AlexZavatone:className是脚本扩展添加的一种方法,仅在Mac OS X上可用,即使那样,它的工作方式也很复杂,因为它没有完全记录(或者至少不是我上次检查的时间)。NSStringFromClass()是正确的解决方法。
dreamlax 2012年

1

这是另一种减少打字的方法:

NSString *name = [NSArray description];

7
不能保证做到所要求的。通常忽略该方法以提供对象及其包含的数据的描述。
亚历克斯·韦恩

3
我知道它是作为一种INSTANCE方法被覆盖的,但是+ description CLASS METHOD被覆盖的频率是多少?无论如何,如果不是每个班级都值得考虑……我不认为需要降级。
舍温·扎德

1
@SherwinZadeh:我认为在实践中,您不太可能找到已被覆盖的类+description,但是,从理论上讲,这不是的目的+description,因此此方法对于确定类名很脆弱。
dreamlax

1

考虑以下替代方法:

const char *name = class_getName(cls);

它更快,因为不必分配NSString对象并将ASCII转换为任何NSString表示形式。就是这样NSStringFromClass()实现的。


这对我很有用,但需要在文件顶部添加#import <objc / runtime.h>。
Sparklellama
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.