Classe Objective-C -> chaîne comme: [NSArray className] -> @ «NSArray»

128

J'essaie d'obtenir un nom de chaîne d'une classe à partir de l'objet de classe lui-même.

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

J'ai trouvé object_getClassName(id obj)mais cela nécessite qu'une instance lui soit transmise, et dans mon cas, c'est un travail inutile.

Alors, comment puis-je obtenir une chaîne à partir d'un objet de classe et non d' une instance?

Alex Wayne
la source

Réponses:

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

Vous pouvez même revenir en arrière:

Class arrayClass = NSClassFromString (name);
id anInstance = [[arrayClass alloc] init];
dreamlax
la source
Merci! Comment est NSStringFromClassmis en œuvre? Est-il plus performant de stocker le nom de la classe dans une static NSStringvariable?
ma11hew28
13
@MattDiPasquale: Tous les noms de classe sont stockés quelque part dans le runtime Objective-C (les composants internes du runtime sont pour la plupart cachés de l'application et exposés uniquement via quelques fonctions API). Chaque objet de classe (par exemple [NSArray class]) est en fait un struct. Le structcontient beaucoup d'informations sur la classe, y compris son nom, les méthodes qu'elle implémente, la superclasse, etc. en NSStringFromClasstire simplement le nom de la classe structet le convertit en un fichier NSString. Ne stockez pas le nom de la classe dans un static NSString, cela n'offrira aucun avantage en termes de performances.
dreamlax
3
@MattDiPasquale: NSClassFromStringfonctionne un peu différemment. Étant donné que tous les noms de classe existent quelque part dans le runtime Objective-C, NSClassFromStringprend la chaîne et explore la liste des classes maintenues par le runtime à la recherche de la classe qui porte le nom donné. S'il le trouve, il le renvoie, sinon il retourne Nil.
dreamlax
2
@MattDiPasquale: "Comment NSStringFromClass est-il implémenté?" si vous voulez vraiment savoir, il utilise probablement class_getName()dans le runtime, qui renvoie une chaîne C
user102008
2
@AlexZavatone: classNameest une méthode ajoutée par les extensions de script qui n'est disponible que sur Mac OS X, même dans ce cas, elle est capricieuse dans son fonctionnement car elle n'est pas entièrement documentée (ou du moins ce n'était pas la dernière fois que j'ai vérifié). NSStringFromClass()est la bonne façon de procéder.
dreamlax
1

Voici une façon différente de le faire avec un peu moins de frappe:

NSString *name = [NSArray description];
Sherwin Zadeh
la source
7
Ce n'est pas garanti de faire ce qui est demandé. Cette méthode est généralement remplacée pour fournir une description de l'objet et des données qu'il contient.
Alex Wayne
3
Je sais qu'elle est remplacée en tant que méthode INSTANCE mais à quelle fréquence la + description CLASS METHOD est-elle remplacée? En tout cas, cela vaut la peine d'envisager sinon pour chaque classe ... Je ne pense pas qu'un déclassement était nécessaire.
Sherwin Zadeh
1
@SherwinZadeh: Je pense qu'en pratique, il est peu probable que vous trouviez des classes qui ont été remplacées +description, cependant, en théorie, ce n'est pas le but +description, et cette méthode est donc fragile pour déterminer les noms de classe.
dreamlax
1

Considérez cette alternative:

const char *name = class_getName(cls);

C'est beaucoup plus rapide, car il n'a pas besoin d'allouer un objet NSString et de convertir ASCII en une NSStringreprésentation quelconque . Voilà comment NSStringFromClass()est mis en œuvre.

merveille.
la source
C'était utile pour moi, mais il fallait ajouter #import <objc / runtime.h> en haut du fichier.
Sparklellama le