classe perso, archivage et récupération
sisopetron
Membre
Bonjour,
Je m'adresse à vous parce que je ne trouve pas la solution à mon problème. Je vous explique brièvement ce que je cherche à faire:
J'ai une classe perso appelée MyNumbers qui ne contient que des integer :
Les instances de cette classe sont placées dans un mutable array myNumbersList et cet array est affiché dans une tableView. Cette clase implémente le protocole NSCoding de cette manière :
Le controleur de ma tableView implémente deux méthodes pour la sauvagarde et la restauration de myNumbersList :
Ces deux méthodes ont l'air de fonctionner correctement : au démarrage de mon application je retrouve bien les valeurs dans ma tableView.
Mais, il y a un problème : l'application plante sur cette méthode :
et plus particulièrement sur la ligne en rouge.
Au premier lancement, le débogueur ne donne aucunes informations. Quand je relance le programme, il me donne enfin une info : -[__NSCFType objectAtIndex:]: unrecognized selector sent to instance
Vous l'aurez compris, je ne comprends pas où est le problème. J'ai donc besoin de votre aide.
Merci à vous.
Je m'adresse à vous parce que je ne trouve pas la solution à mon problème. Je vous explique brièvement ce que je cherche à faire:
J'ai une classe perso appelée MyNumbers qui ne contient que des integer :
@interface MyNumbers : NSObject <NSCoding> { <br />
int number1;<br />
int number2;<br />
int number3;<br />
int number4;<br />
int number5;<br />
int number6;<br />
}<br />
@property int number1;<br />
@property int number2;<br />
@property int number3;<br />
@property int number4;<br />
@property int number5;<br />
@property int number6;<br />
@end
Les instances de cette classe sont placées dans un mutable array myNumbersList et cet array est affiché dans une tableView. Cette clase implémente le protocole NSCoding de cette manière :
-(void)encodeWithCoder:(NSCoder *)encoder {<br />
[encoder encodeInt:number1 forKey:@"number1"];<br />
[encoder encodeInt:number2 forKey:@"number2"];<br />
[encoder encodeInt:number3 forKey:@"number3"];<br />
[encoder encodeInt:number4 forKey:@"number4"];<br />
[encoder encodeInt:number5 forKey:@"number5"];<br />
[encoder encodeInt:number6 forKey:@"number6"]; <br />
}<br />
-(id)initWithCoder:(NSCoder *)decoder {<br />
[super init]; <br />
number1 = [decoder decodeIntForKey:@"number1"];<br />
number2 = [decoder decodeIntForKey:@"number2"];<br />
number3 = [decoder decodeIntForKey:@"number3"];<br />
number4 = [decoder decodeIntForKey:@"number4"];<br />
number5 = [decoder decodeIntForKey:@"number5"];<br />
number6 = [decoder decodeIntForKey:@"number6"]; <br />
return self;<br />
}
Le controleur de ma tableView implémente deux méthodes pour la sauvagarde et la restauration de myNumbersList :
- (IBAction)saveGridsToUserDefaults:(id)sender { <br />
[[tvMyNumbers window] endEditingFor:nil]; <br />
NSUserDefaults* standardUserDefaults = [NSUserDefaults standardUserDefaults];<br />
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:myNumbersList];<br />
[standardUserDefaults setValue:data forKey:@"grids"];<br />
[standardUserDefaults synchronize];<br />
}<br />
-(NSMutableArray*)retrieveGridsFromUserDefaults {<br />
NSMutableArray *newArray = nil; <br />
NSUserDefaults* standardUserDefaults = [NSUserDefaults standardUserDefaults];<br />
NSData *data = [standardUserDefaults valueForKey:@"grids"];<br />
newArray = [NSKeyedUnarchiver unarchiveObjectWithData:data]; <br />
return newArray;<br />
}
Ces deux méthodes ont l'air de fonctionner correctement : au démarrage de mon application je retrouve bien les valeurs dans ma tableView.
Mais, il y a un problème : l'application plante sur cette méthode :
- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {<br />
NSString *identifier = [tableColumn identifier];<br />
[color=#ff0000]MyNumbers *myNumbers = [myNumbersList objectAtIndex:row];[/color]<br />
return [myNumbers valueForKey:identifier]; <br />
}
et plus particulièrement sur la ligne en rouge.
Au premier lancement, le débogueur ne donne aucunes informations. Quand je relance le programme, il me donne enfin une info : -[__NSCFType objectAtIndex:]: unrecognized selector sent to instance
Vous l'aurez compris, je ne comprends pas où est le problème. J'ai donc besoin de votre aide.
Merci à vous.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Bonjour,
C'est plutôt
D'où l'erreur que tu décris n'existe plus.
Affiche avec NSStringFromClass le nom de la class de myNumbersList
pour être sur que c'est un bien un NSMutableArray retourner par ta fonction.
Ce qui peut avoir 2 causes possibles :
- La relecture de tes données se fait mal, genre tu penses enregistrer un NSArray mais en fait tu enregistres un autre objet, du coup quand tu le relis c'est pas un NSArray. Comme tu as bien fait les choses de façon symétrique à priori ce n'est pas ça, ton code de lecture et d'écriture me semble correct
- Tu as oublié de retenir l'objet que tu as récupéré dans myNumbersList et du coup cet objet est relâché de la mémoire sans avoir été retenu. Du coup l'objet est détruit, et la variable myNumbersList quant à elle ne pointe plus sur rien de concret, ou pointe vers du grand n'importe quoi, l'objet vers lequel elle pointait avant n'existant plus en mémoire.
C'est à priori vu ton code cette deuxième option qui est la cause de ton problème, puisqu'après avoir récupéré ton tableau avec [tt]myNumbersList = [self retrieveGridsFromUserDefaults];[/tt] donc avoir récupéré un objet "autorelease", tu n'as pas fait de retain dessus pour le garder.
Si tu ne charges qu'une seule fois cette liste myNumbersList, il suffit de rajouter un retain. Si tu la recharges à différents endroits dans ton programme et pas que dans la méthode de lancement de l'appli, pense à éventuellement faire aussi un "release" sur la valeur précédente de myNumbersList avant de lui affecter une nouvelle valeur (et de retain cette nouvelle valeur). Ou alors mieux encore, fait un setter. Ou le plus simple et le plus efficace, utilise les @property.