2009-08-10 6 views
0

J'ai un objet Obj-C "parent" contenant (dans une collection) un groupe d'objets dont les variables d'instance se pointent entre elles, éventuellement de manière circulaire (peur non, pas de rétention entre ces «frères et soeurs»). J'écris l'objet parent en XML, ce qui implique bien sûr (entre autres) d'écrire ses "enfants", sans ordre particulier, et en raison de la circularité possible, je remplace ces références entre les enfants par des identifiants uniques que chaque enfant a . Le problème est de lire ce XML en arrière ... comme je crée un "enfant", je tombe sur un ID, mais il n'y a aucune garantie que l'objet auquel il fait référence a été créé pour le moment. Puisque les références sont éventuellement circulaires, il n'y a même pas d'ordre dans lequel les lire qui résout ce problème.Lecture d'un pointeur XML sans être sûr que l'instance Obj-C correspondante existe

Que dois-je faire? Ma solution actuelle consiste à remplacer (dans les variables d'instance réelles) les références par des chaînes contenant les identifiants uniques. C'est méchant, cependant, parce que pour utiliser ces variables d'instance, au lieu de quelque chose comme [oneObject aSibling] je dois maintenant faire quelque chose comme [theParent childWithID:[oneObject aSiblingID]]. Je suppose que je pourrais créer une méthode aSibling pour simplifier les choses, mais il semble qu'il y ait une façon plus propre que tout cela. Y a-t-il?

Répondre

2

Cela sonne énormément comme si vous réinventiez NSCoding car il gère les références circulaires, etc ... Maintenant, il pourrait y avoir une bonne raison de réinventer cette roue. Vous seul pouvez répondre cette question.

Dans tous les cas, on dirait que vous voulez un processus d'archivage en deux passes. Passe 1: Récupérez tous les objets du magasin de sauvegarde et reconstituez-les. Lorsque chaque objet sort, insérez-le dans un dictionnaire ou une carte avec l'UID comme clé. Chaque fois qu'un objet contient un UID, enregistrez l'objet comme devant être réparé; ajoutez-le à un ensemble ou un tableau que vous gardez pendant l'archivage. Passe 2: Parcourez l'ensemble ou la matrice d'objets qui doivent être réparés et corrigez-les, en remplaçant les UID par des objets de la carte que vous avez construite dans la passe # 1. J'ai rencontré un peu d'erreur d'analyse sur ce dernier paragraphe. En supposant que vos classes sont raisonnablement déclarées, elles devraient pouvoir se réparer à la volée.

(Tout compte fait, c'est exactement le type de structure de données qui est beaucoup plus facile à implémenter dans un environnement GC.Si vous ciblez Mac OS X, pas l'iPhone, activer le GC va faire votre vie plus facile, plus probable)

0

Le processus de sérialisation de Java fait à peu près la même chose. Chaque objet qu'il écrit, il met dans une table 'objets précédemment vu'. Quand il s'agit d'écrire une référence ultérieure, si l'objet est vu auparavant, il écrit un code qui indique qu'il s'agit d'un objet précédemment vu dans la liste. Lorsque l'inverse se produit, chaque fois qu'il voit une telle référence, il la remplace à la volée par l'instance précédente. Cette approche signifie que vous n'avez pas besoin d'utiliser cette carte pour toutes les instances, mais que la substitution se produit uniquement pour les objets que vous avez vus une seconde fois. Cependant, vous devez toujours pouvoir référencer de façon unique la première instance écrite, que ce soit par un pointeur sur une partie de la structure de données ou non dépend de ce que vous écrivez.

Questions connexes