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

128

Estou tentando obter um nome de seqüência de caracteres de uma classe do próprio objeto de classe.

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

Descobri, object_getClassName(id obj)mas isso exige que uma instância seja passada a ela e, no meu caso, é um trabalho desnecessário.

Então, como posso obter uma string de um objeto de classe, e não uma instância?

Alex Wayne
fonte

Respostas:

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

Você pode até voltar para o outro lado:

Class arrayClass = NSClassFromString (name);
id anInstance = [[arrayClass alloc] init];
dreamlax
fonte
Obrigado! Como é NSStringFromClassimplementado? É mais eficiente armazenar o nome da classe em uma static NSStringvariável?
precisa saber é o seguinte
13
@MattDiPasquale: todos os nomes de classe são armazenados em algum lugar no tempo de execução do Objective-C (os internos do tempo de execução são ocultos na maioria das vezes do aplicativo e expostos apenas por algumas funções da API). Cada objeto de classe (por exemplo [NSArray class]) é realmente um struct. O structcontém muitas informações sobre a classe, incluindo seu nome, os métodos que implementa, a superclasse etc. NSStringFromClassapenas extrai o nome da classe structe a converte em um NSString. Não armazene o nome da classe em static NSString, ele não oferecerá nenhuma vantagem de desempenho.
dreamlax
3
@MattDiPasquale: NSClassFromStringfunciona um pouco diferente. Como todos os nomes de classe existem em algum lugar do tempo de execução Objective-C, NSClassFromStringpega a sequência e explora a lista de classes mantidas pelo tempo de execução procurando pela classe que tem o nome fornecido. Se o encontrar, ele retornará, caso contrário, retornará Nil.
dreamlax
2
@MattDiPasquale: "Como o NSStringFromClass é implementado?" se você realmente quer saber, provavelmente usa class_getName()no tempo de execução, que retorna uma string C
user102008
2
@AlexZavatone: classNameé um método adicionado pelas extensões de script que só está disponível no Mac OS X; mesmo assim, é meticuloso na maneira como funciona porque não está totalmente documentado (ou pelo menos não foi a última vez que verifiquei). NSStringFromClass()é a maneira correta de fazer isso.
dreamlax
1

Aqui está uma maneira diferente de fazer isso com um pouco menos de digitação:

NSString *name = [NSArray description];
Sherwin Zadeh
fonte
7
Isso não garante que você faça o que é solicitado. Esse método geralmente é substituído para fornecer uma descrição do objeto e dos dados que ele contém.
Alex Wayne
3
Eu sei que ele é substituído como um método INSTANCE, mas com que freqüência o método de descrição da descrição é substituído? De qualquer forma, vale a pena considerar, se não para todas as classes ... Eu não acho que um downgrade foi necessário.
Sherwin Zadeh
1
@ SherwinZadeh: Acho que, na prática, é improvável que você encontre classes que substituíram +description, no entanto, em teoria, esse não é o objetivo +descriptione, portanto, esse método é frágil para determinar os nomes das classes.
dreamlax
1

Considere esta alternativa:

const char *name = class_getName(cls);

É muito mais rápido, pois não precisa alocar o objeto NSString e converter ASCII para qualquer NSStringrepresentação. É assim que NSStringFromClass()é implementado.

wonder.mice
fonte
Isso foi útil para mim, mas era necessário adicionar #import <objc / runtime.h> na parte superior do arquivo.
precisa