4 votes

iPhone / Objective-C : NSMutableArray writeToFile n'écrit pas dans le fichier. Il renvoie toujours NO

J'essaie de sérialiser deux NSMutableArrays de NSObjects qui mettent en œuvre la NSCoding protocole. Cependant, il fonctionne pour un ( stacks ) et pas l'autre ( cards ). J'ai le bloc de code suivant :

-(void) saveCards
{
    NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString* documentsDirectory = [paths objectAtIndex:0];

    NSString* cardsFile = [documentsDirectory stringByAppendingPathComponent:@"cards.state"];
    NSString* stacksFile = [documentsDirectory stringByAppendingPathComponent:@"stacks.state"];
    BOOL c = [rootStack.cards writeToFile:cardsFile atomically:YES];
    BOOL s = [rootStack.stacks writeToFile:stacksFile atomically:YES];
}

J'exécute cette méthode en utilisant le débogueur, et après l'exécution des deux dernières lignes de code, je vérifie les valeurs des deux paramètres suivants BOOL s. BOOL c est NO y BOOL s est YES . Le site stacks est en fait vide (ce qui est probablement la raison pour laquelle cela fonctionne). Le site cards a un contenu. Pourquoi le tableau avec contenu échoue-t-il ? Je n'arrive pas à comprendre. J'ai parcouru de nombreux fils de discussion sur SOF, et chacun d'entre eux dit que le problème vient du fait que le niveau de protection des fichiers qu'ils écrivaient les empêchait d'écrire. Ce n'est pas mon problème, car j'écris dans le dossier Documents. J'ai vérifié deux fois et trois fois que ni l'un ni l'autre de ces fichiers n'était protégé. rootStack.cards ni rootStack.stacks est nul. Et j'ai vérifié que les cartes ont bien un contenu.

Voici les méthodes du codeur pour ma classe Notecard (j'ai ajouté toutes les if dans le cadre de la résolution de ce problème, afin de s'assurer que l'encodage des valeurs nulles ne casse pas quelque chose) :

-(void) encodeWithCoder:(NSCoder *)encoder
{
    if(text)
        [encoder encodeObject:text forKey:@"text"];
    if(backText)
        [encoder encodeObject:backText forKey:@"backText"];
    if(x)
        [encoder encodeObject:x forKey:@"x"];
    if(y)
        [encoder encodeObject:y forKey:@"y"];
    if(width)
        [encoder encodeObject:width forKey:@"width"];
    if(height)
        [encoder encodeObject:height forKey:@"height"];
    if(timeCreated)
        [encoder encodeObject:timeCreated forKey:@"timeCreated"];
    if(audioManagerTicket)
        [encoder encodeObject:audioManagerTicket forKey:@"audioManagerTicket"];
    if(backgroundColor)
        [encoder encodeObject:backgroundColor forKey:@"backgroundColor"];
}

-(id) initWithCoder:(NSCoder *)decoder
{
    self = [super init];
    if(!self)
        return nil;

    self.text               = [decoder decodeObjectForKey:@"text"];
    self.backText           = [decoder decodeObjectForKey:@"backText"];
    self.x                  = [decoder decodeObjectForKey:@"x"];
    self.y                  = [decoder decodeObjectForKey:@"y"];
    self.width              = [decoder decodeObjectForKey:@"width"];
    self.height             = [decoder decodeObjectForKey:@"height"];
    self.timeCreated        = [decoder decodeObjectForKey:@"timeCreated"];
    self.audioManagerTicket = [decoder decodeObjectForKey:@"audioManagerTicket"];
    self.backgroundColor    = [decoder decodeObjectForKey:@"backgroundColor"];

    return self;
}

chaque champ est soit une NSString, soit un NSNumber, soit une UIColor.

Merci pour toute aide

14voto

bbum Points 124887

Vous confondez les listes de propriétés avec l'archivage. C'est facile à faire.

writeToFile:atomically: exige que le contenu soit conforme aux listes de propriétés, c'est-à-dire que tous les objets du tableau soient une instance de l'une des classes autorisées dans les listes de propriétés (dictionnaires, chaînes de caractères, données, tableaux, etc...).

Voir : writeToFile:atomically:'s documentation .

Ce que vous voulez, c'est NSArchiver et, plus précisément, de lire le guide d'archivage .

3voto

Jason Jenkins Points 2594

Le site writeToFile:atomically: méthode sur NSMutableArray que vous appelez ne fonctionne que si tous les éléments du tableau sont des objets de liste de propriétés ( NSString , NSData , NSArray o NSDictionary objets). Il fait NSPropertyListSerialization . Ce n'est pas la même chose que l'archivage à clé qui est effectué à l'aide de NSKeyedArchiver et du protocole NSCoding. Voir le Guide des archives et de la sérialisation pour Cocoa pour les détails.

Le problème spécifique ici est que UIColor n'est pas un objet de liste de propriétés. Il implémente cependant la fonction NSCoding et devrait fonctionner dans une archive. Essayez quelque chose comme

BOOL c  = [NSKeyedArchiver archiveRootObject:rootStack.card
                                      toFile:cardsFile];
BOOL s  = [NSKeyedArchiver archiveRootObject:rootStack.stacks
                                      toFile:stacksFile];

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X