iPhone / Objective-C: NSMutableArray writeToFile не будет записывать в файл. Всегда возвращает НЕТ - PullRequest
4 голосов
/ 04 мая 2010

Я пытаюсь сериализовать два NSMutableArrays из NSObjects, которые реализуют протокол NSCoding. Однако это работает для одного (stacks), а не для другого (cards). У меня есть следующий блок кода:

-(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];
}

Я выполняю этот метод с помощью отладчика, и после запуска двух последних строк кода я проверяю значения двух BOOL s. BOOL c - это NO, а BOOL s - это YES. Массив stacks на самом деле пустой (возможно, именно поэтому он работает). Массив cards содержит содержимое. Почему происходит сбой массива с содержимым? Я не могу понять это. Я просмотрел многочисленные темы по SOF, каждая из которых говорит, что проблема в том, что уровень защиты файлов, которые они записывали, мешал им писать. Это не моя проблема, так как я пишу в папку «Документы». Я дважды и трижды проверил, что ни rootStack.cards, ни rootStack.stacks не равны нулю. И я проверил, что на картах действительно есть контент.

Вот методы кодирования для моего класса Notecard (я добавил все if характеристик как часть попытки решить эту проблему, чтобы убедиться, что попытка кодировать nil-значения ничего не нарушает):

-(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;
}

каждое поле является NSString, NSNumber или UIColor.

Спасибо за любую помощь

Ответы [ 2 ]

14 голосов
/ 04 мая 2010

Вы путаете списки свойств с архивированием. Это легко сделать.

writeToFile:atomically: требует, чтобы содержимое соответствовало списку свойств; то есть все объекты в массиве являются экземплярами одного из классов, разрешенных в списках свойств (словари, строки, данные, массивы и т. д.).

См .: writeToFile: атомно: документация .

Что вам нужно, это NSArchiver и, более конкретно, прочитать руководство по архивированию .

3 голосов
/ 04 мая 2010

Метод writeToFile:atomically: в NSMutableArray, который вы вызываете, работает, только если все элементы массива являются объектами списка свойств (NSString, NSData, NSArray или NSDictionary объектов.) делает NSPropertyListSerialization . Это не то же самое, что архивирование на основе ключей, которое выполняется с использованием NSKeyedArchiver и протокола NSCoding. Подробнее см. Руководство по архивам и сериализации для какао .

Особая проблема заключается в том, что UIColor не является объектом списка свойств. Однако он реализует протокол NSCoding и должен работать в архиве. Попробуйте что-то вроде

BOOL c  = [NSKeyedArchiver archiveRootObject:rootStack.card
                                      toFile:cardsFile];
BOOL s  = [NSKeyedArchiver archiveRootObject:rootStack.stacks
                                      toFile:stacksFile];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...