Класс Objective-C -> строка вида: [NSArray className] -> @ «NSArray»

128

Я пытаюсь получить строковое имя класса из самого объекта класса.

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

Я нашел, object_getClassName(id obj)но для этого требуется передать ему экземпляр, а в моем случае это ненужная работа.

Итак, как я могу получить строку из объекта класса, а не из экземпляра?

Алекс Уэйн
источник

Ответы:

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

Можно даже вернуться назад:

Class arrayClass = NSClassFromString (name);
id anInstance = [[arrayClass alloc] init];
dreamlax
источник
Спасибо! Как это NSStringFromClassреализовано? Более производительно хранить имя класса в static NSStringпеременной?
ma11hew28
13
@MattDiPasquale: все имена классов хранятся где-то в среде выполнения Objective-C (внутренняя часть среды выполнения в основном скрыта от приложения и доступна только через несколько функций API). Каждый объект класса (например [NSArray class]) на самом деле является файлом struct. structСодержит много информации о классе, в том числе его название, методы он реализует, суперкласс и т.д. NSStringFromClassпросто тянет имя класса из этого structи преобразует его в NSString. Не храните имя класса в a static NSString, это не даст никакого преимущества в производительности.
dreamlax
3
@MattDiPasquale: NSClassFromStringработает немного иначе. Поскольку все имена классов существуют где-то в среде выполнения Objective-C, NSClassFromStringберет строку и исследует список классов, поддерживаемых средой выполнения, в поисках класса с заданным именем. Если он его находит, он его возвращает, иначе он возвращается Nil.
dreamlax
2
@MattDiPasquale: "Как реализован NSStringFromClass?" если вы действительно хотите знать, он, вероятно, использует class_getName()во время выполнения, который возвращает строку C
user102008
2
@AlexZavatone: classNameэто метод, добавленный расширениями сценариев, который доступен только в Mac OS X, даже в этом случае он привередлив в том, как он работает, потому что он не полностью документирован (или, по крайней мере, это был не последний раз, когда я проверял). NSStringFromClass()это правильный способ сделать это.
dreamlax
1

Вот другой способ сделать это с меньшим набором текста:

NSString *name = [NSArray description];
Шервин Заде
источник
7
Это не гарантирует выполнение того, что требуется. Этот метод обычно игнорируется, чтобы предоставить описание объекта и содержащихся в нем данных.
Alex Wayne
3
Я знаю, что он переопределяется как метод INSTANCE, но как часто + description CLASS METHOD переопределяется? В любом случае об этом стоит подумать, если не для каждого класса ... Я не думаю, что требовалось понижение рейтинга.
Шервин Заде
1
@SherwinZadeh: Я думаю, что на практике вы вряд ли найдете классы, которые были переопределены +description, однако теоретически это не цель +description, и поэтому этот метод хрупкий для определения имен классов.
dreamlax
1

Рассмотрим эту альтернативу:

const char *name = class_getName(cls);

Это намного быстрее, так как не нужно выделять объект NSString и преобразовывать ASCII в любое NSStringпредставление. Вот как NSStringFromClass()это реализовано.

wonder.mice
источник
Это было полезно для меня, но нужно было добавить #import <objc / runtime.h> в начало файла.
Sparklellama