2009-06-23 12 views
0

La version 1.0 d'une application possède un modèle de données qui est enregistré/chargé à l'aide des classes NSKeyed (Un) Archiver, car toutes les classes de modèle adhèrent au protocole NSCoding. Supposons que le existe hiérarchie suivante:Chargement par programme d'un modèle objet créé à l'aide de NSCoding

-> Houses (NSMutableArray) 
-> -> House (Custom Object) 
-> -> -> Color (3 ints, RGB) 
-> -> -> Number of Residents (int) 

dire qu'il ya des fichiers existants stockés dans une telle manière, mais doivent être chargés dans la version 2.0 de l'application pour la compatibilité ascendante, en utilisant les éléments suivants plus récent modèle de données:

-> Neighborhood (Maintains NSMutableArray, among other properties) 
-> -> TownHouse 
-> -> -> Color (3 ints, RGB) 
-> -> -> Occupants (NSMutableArray) 
-> -> (Other types of houses) 

De toute évidence, certaines données seront manquantes et devront être remplies. un objet de base "Occupant" devra être créé pour chacun des "nombres de résidents" qui existaient auparavant. Ce que je recherche est un moyen de charger par programme dans le modèle de données précédent, surtout si j'ai seulement une liste des classes/hiérarchie, et pas les fichiers .m/.h eux-mêmes.

donc ce que je veux faire est (en supposant que j'ai un fichier Houses.data, qui a été publié en feuilleton en utilisant le tableau Maisons):

NSFile *legacyFile; 
Neighborhood *hood = [Neighborhood neighborhoodFromLegacyFile:legacyFile]; 

Toutes les idées?

Répondre

1

Je pense que l'astuce ici est d'utiliser la fonction setClass: forClassName: fournie par NSKeyedUnarchiver. Il vous permet de dire: "Utilisez la classe TownHouse pour désérialiser toutes les instances de la classe House."

Ensuite, vous devez modifier la fonction initWithCoder: de votre TownHouse pour décoder l'une ou l'autre hiérarchie. Vous pouvez accomplir cela en appelant decodeObject ou decodeObjectForKey: puis en utilisant isKindOfClass: pour voir quel type d'objet vous avez affaire. Vous pouvez également utiliser containsValueForKey: pour vérifier certaines clés avant d'essayer de les lire.

J'espère que cela aide!

+0

Ça fonctionne comme ça! Un problème est que le tableau "Maisons", avec quelques autres objets, ont été enveloppés dans un NSArray. Cela facilitait la sérialisation d'un objet en appelant [NSKeyedArchiver archivedDataWithRootObject: (NSArray *) topLevelArray]; Pour récupérer ceci, j'avais utilisé [NSKeyedUnarchiver unarchiveObjectWithData: topLevelArrayData] ;. Alors, comment puis-je utiliser la méthode unarchiveObjectWithData: puisqu'il s'agit d'une méthode de classe, avec une instance d'un NSKeyedUnarchiver personnalisé? –

+0

Salut Craig! La classe NSKeyedUnarchiver fournit la fonction setClass: forClassName: au niveau de la classe et de l'instance, ce qui vous permet de dire [NSKeyedUnarchiver setClass: forClassName:], puis d'utiliser [NSKeyedUnarchiver unarchiveObjectWithData: topLevelArrayData]. Vous pouvez créer une instance de NSKeyedUnarchiver si vous le souhaitez, mais ce n'est pas obligatoire. Il devrait utiliser les réglages que vous avez fournis avant la main de toute façon. –