Précisions sur NSCoding
skimpy
Membre
Bonsoir,
Je viens d'implémenter le protocole NSCoding pour mon projet afin de sauvegarder les données. L'enregistrement et le chargement se font bien mais j'aimerais avoir un renseignement :
Lorsque les données sont "désarchivées", est-ce que l'instanciation d'un objet se fait par le constructeur ? Je demande ça car dans une de mes classes j'utilise un constructeur initWithParameters (et pas le simple init - j'ai bien fait attention de faire un initialisateur désigné)
Qu'en est-il du compteur de référence ? Il est placé automatiquement à 1 ?
Merci.
Je viens d'implémenter le protocole NSCoding pour mon projet afin de sauvegarder les données. L'enregistrement et le chargement se font bien mais j'aimerais avoir un renseignement :
Lorsque les données sont "désarchivées", est-ce que l'instanciation d'un objet se fait par le constructeur ? Je demande ça car dans une de mes classes j'utilise un constructeur initWithParameters (et pas le simple init - j'ai bien fait attention de faire un initialisateur désigné)
Qu'en est-il du compteur de référence ? Il est placé automatiquement à 1 ?
Merci.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Ensuite, à toi de faire ensorte que le initWithCoder: appelle ton initWithParameters: .
Petit exemple où les paramètres sont sous forme d'un dictionnaire.
Voila, c'est "tout" (attention si tu fais un copier-coller de ce code, je ne suis pas sûr qu'il n'y ait pas d'erreure). Evidemment ca demande que tu aies correctement encodé tes paramètres dans encodeWithCoder:, mais tu l'as apparemment bien fait
Ma classe hérite de NSObject et a 2 initialisateurs : - (id)init et - (id)initWithRoot:(NSMutableDictionary *)aData. L'initialisateur init fait appel à initWithRoot avec des paramètres par défaut.
Ce que je ne comprends pas c'est le self = [super init] : le "super" appelle bien l'initialisateur de la classe parent (soit NSObject) ? Donc comment les objets data et child sont instancés (j'ai mis un NSLog dans mon init et initWithRoot mais lorsque j'utilise ma fonction de "désarchivage", ils ne sont jamais appelés) ?
super appelle la superclasse (classe parent) et non pas ta propre classe et donc, pour initialiser les objets data et child, il faut que tu appelles [self init] (tu t'appelle toi-même en quelque sorte). Et ensuite, tu pourras faire setData: et setChild: comme dans ton code.
Donc pour que ton code marche, il te suffi de changer le [super init] en [self init]
Par contre, quand je faisais mon self = [super init], ça fonctionnait correctement (mes données sauvées sur disque étaient bien affichées lors du chargement de l'appli) ... c'est bizarre ou normal ?
Donc au début, lorsque que tu fais un setData: par exemple, _data == nil le fait que tu fasses un setData: permet de faire que _data pointe sur quelque chose, et donc finalement que tes données s'affichent.
Mais un problème aurait pus avoir lieu si par exemple, tu avais une données qui s'initialise dans le init mais dont tu ne change pas la valeur après (tu ne fais pas de set...: ). Je n'ai pas d'idée qui me viens à l'esprit, mais je pense que tu auras compris
Bonne chance pour la suite :fouf):
Aaaatttention ! Il faut faire l'inverse, à savoir :
En effet, imaginons que le paramètre de setData soit _data lui-même, en théorie il ne doit rien se passer. La deuxième solution fait donc +1-1 au compteur de référence (très bien), tandis que la première solution (la mauvaise) fait -1+1. Le problème est que si le compteur était à 1, il passe à 0, donc l'objet est détruit avant d'avoir pu faire le +1.
(Un retain fait +1, un release fait -1)
+
Chacha