2010-08-13 6 views
3

Je tente d'instancier des classes à partir de différentes sources XML. Les cas des noms de classes sont incohérents (camel, upper, lower) entre ces sources. Est-ce qu'un équivalent de NSClassFromString existe pour cela? Par exemple, ce qui permet:NSClassFromString Insensible à la casse Objectif-C

Person *person = [[NSClassFromCaseInsensitiveString("Person") alloc] init]; 
Person *person = [[NSClassFromCaseInsensitiveString("person") alloc] init]; 
Person *person = [[NSClassFromCaseInsensitiveString("PERSON") alloc] init]; 

Répondre

3

Vous êtes probablement coincé avec recherche dans la liste des classes, pouvant être obtenus à partir objc_getClassList

+0

Merci, je suppose que je vais devoir écrire mon propre matcher insensible à la casse. –

6

faire un cas NSString insensible à l'aide d'une des méthodes de capitalisation dans NSString (-capitalizedString par exemple), utilisez-le comme param pour NSClassFromString

Edit: voici le code basé sur votre exemple de personne. (En supposant stringFromXML est un NSString que vous analysables à partir de votre code XML qui pourrait contenir toute forme du mot « personne »

NSString *personString = stringFromXML; 
Person *person = NSClassFromString([personString capitalizedString]); 
+1

cela ne fonctionnera que tant que vous n'avez pas de noms de classe camelCased – cobbal

+0

oui je suis d'accord, et si c'est le cas, votre réponse est la seule solution viable. Je n'ai pas vu la mention de Camel et supposé de l'exemple ce serait des noms simples :) –

+0

Merci Jesse. Cependant, j'ai besoin de soutenir les noms de classe chamelés. Appréciez la réponse si! –

1

Vous pourrait utiliser les méthodes de capitalisation NSString, si vous êtes assuré que le nom de la classe ressemblera à cela.Une fonction générale comme vous décrivez n'est pas disponible, et ne le sera probablement pas, pour la simple raison que les noms de classe ne sont pas insensibles à la casse

@interface Person : NSObject 
{ 

} 

@end 

@interface PERSON : NSObject 
{ 

} 

@end 

fonctionnera et déclarera deux types de classe différents. Bien qu'en toute honnêteté, avoir des cours avec des noms identiques à l'exception du cas serait juste un mauvais style en premier lieu.

3

Veuillez ne pas faire ceci. Vous laissez des classes arbitraires arbitraires (je suppose que le téléchargement sur HTTP) instancié arbitrairement dans votre application. C'est mauvais, et il est difficile de savoir comment mauvais parce qu'il peut instancier toute classe chargée dans votre application (y compris ceux dans des cadres privés).

Tenir compte utiliser quelque chose comme

NSDictionary * classesByLowercaseString = [NSDictionary dictionaryWithObjectsAndKeys: 
    [Person class], @"person", 
    [Blah class[, @"blah", 
    nil]; 
[classesByLowercaseString objectForKey:[xmlClassName lowercaseString]]; 

Notez également que les noms balise XML sont censés être sensibles à la casse.

+2

+1 pour note de sécurité ici. Étudier la liste des classes de modèles possibles explicitement. –

+0

+1 est vraiment la meilleure façon d'y aller – cobbal

+0

De peur que quelqu'un pense que les implications de sécurité de l'instanciation des classes nommées par l'entrée sont académiques, [cela a vraiment mordu les gens de Ruby on Rails] (http://blog.codeclimate.com/blog/2013/01/10/rails-remote-code-execution-vulnérabilité-expliqué /). –