J'ai besoin d'analyser un enregistrement XML qui représente une QuizQuestion. L'attribut "type" indique le type de question. J'ai alors besoin de créer une sous-classe appropriée de QuizQuestion basée sur le type de question. Le code suivant fonctionne (déclarations de libération [auto] omis pour plus de clarté):OO Conception Objective-C avec analyse XML
QuizQuestion *question = [[QuizQuestion alloc] initWithXMLString:xml];
if([ [question type] isEqualToString:@"multipleChoiceQuestion"]) {
[myQuestions addObject:[[MultipleChoiceQuizQuestion alloc] initWithXMLString:xml];
}
//QuizQuestion.m
-(id)initWithXMLString:(NSString*)xml {
self.type = ...// parse "type" attribute from xml
// parse the rest of the xml
}
//MultipleChoiceQuizQuestion.m
-(id)initWithXMLString:(NSString*)xml {
if(self= [super initWithXMLString:xml]) {
// multiple-choice stuff
}
}
Bien sûr, cela signifie que le XML est analysé deux fois: une fois pour connaître le type de QuizQuestion, et une fois que lorsque le QuizQuestion approprié est initialisé.
Pour éviter l'analyse syntaxique du XML deux fois, j'ai essayé l'approche suivante:
// MultipleChoiceQuizQuestion.m
-(id)initWithQuizRecord:(QuizQuestion*)record {
self=record; // record has already parsed the "type" and other parameters
// multiple-choice stuff
}
Cependant, cela ne fonctionne pas en raison de la cession « auto = enregistrement »; à chaque fois que MultipleChoiceQuizQuestion essaie d'appeler une méthode d'instance, il essaie d'appeler la méthode sur la classe QuizQuestion à la place.
Quelqu'un peut-il me dire la bonne approche pour analyser XML dans la sous-classe appropriée lorsque la classe parente doit être initialisée pour savoir quelle sous-classe est appropriée?
Ce code me semble très approximatif. [auto-libération] est à la fois dangereux et cruel, car vous forcez votre objet à se suicider. Cela semble dangereux puisque vous finissez par exécuter du code dans une instance de classe qui a été distribuée. Blague à part, une meilleure façon d'obtenir des fonctionnalités similaires pourrait être d'utiliser une fonction d'usine. – Tyler
Il existe des cas (rares) où cette méthodologie est valide et utilisée (par exemple NSManagedObjectContext renvoie une instance de classe différente de initWithEntity: insertIntoManagedObjectContext :), mais je suis d'accord que c'est normalement une mauvaise idée. [auto autorelease] serait plus sûr, cependant. – iKenndac