Как сохранить NSArray с настроенным объектом? - PullRequest
1 голос
/ 20 февраля 2011

У меня есть NSMutableArray, если это строка хранилища, я могу читать и успешно писать, используя этот метод.

[array writeToFile:m_sApplicationPlistPath atomically:YES];

NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:m_sApplicationPlistPath];

, но если мой массив добавляет что-то, что не является простой строкой, дляНапример, я добавляю специальный объект в массив, например:

[array addObject:[[SpecialObject alloc] init]];

Я обнаружил, что не могу прочитать специальный объект, как я могу его решить, спасибо.

Ответы [ 4 ]

3 голосов
/ 20 февраля 2011

Реализация протокола NSCoding. (encodeWithCoder и initWithCoder)

Если вы все еще не можете использовать метод writeToFile: atomically: тогда вам нужно сериализовать NSArray для получения данных, а затем записать их в файл.

NSData *data = NSKeyedArchiver archivedDataWithRootObject:theArray];
3 голосов
/ 20 февраля 2011

Я думаю, вы не можете этого сделать, потому что метод [NSArray writeToFile: atomically:] использует списки свойств, которые доступны только для определенных типов данных (NSString, NSData, NSArray или NSDictionary).

Чтобы записать массив в файл, вы можете заставить SpecialObject соответствовать протоколу NSCoding , а затем сохранить массив, используя - [ NSKeyedArchiver archiveRootObject: toFile:], используя массив как корневой объект.

2 голосов
/ 21 февраля 2011

Вы можете заставить это работать, используя методы, определенные в протоколе NSKeyValueCoding, чтобы преобразовать экземпляры вашего пользовательского класса в экземпляры NSDictionary перед их записью.Вы можете сделать аналогичное преобразование после чтения файла plist обратно, чтобы воссоздать объекты.

Вот пример, который преобразует массив экземпляров пользовательского класса Book в массив словарей, используя dictionaryWithValuesForKeys: метод, объявленный в NSKeyValueCoding (и реализованный NSObject, поэтому все объекты наследуют это поведение):

+ (NSArray *)dictionariesFromBooks:(NSArray *)books
{
    NSMutableArray *bookDicts = [NSMutableArray arrayWithCapacity:[books count]];

    for (Book *currBook in books)
    {
        NSDictionary *currDict = [currBook dictionaryWithValuesForKeys:[Book keys]];
        [bookDicts addObject:currDict];
    }

    return bookDicts;
}

Аналогично, вот метод, который заполняет экземпляры Book с использованием метода NSKeyValueCodingsetValuesForKeysWithDictionary:

+ (NSArray *)booksFromDictionaries:(NSArray *)bookDicts
{
    NSMutableArray *books = [NSMutableArray arrayWithCapacity:[bookDicts count]];

    for (NSDictionary *currDict in bookDicts)
    {
        Book *currBook = [[Book alloc] init];
        [currBook setValuesForKeysWithDictionary:currDict];
        [books addObject:currBook];
        [currBook release];
    }

    return books;
}

Немного поработав, это можно сделать каскадно для вложенных пользовательских объектов.Например, если Book содержал вложенный экземпляр Author, вы можете переопределить NSKeyValueCoding методы, такие как setValue:forKey: и dictionaryWithValuesForKeys:, чтобы преобразовать экземпляр на лету.

0 голосов
/ 20 февраля 2011

Из документов:

Если содержимое массива - это все объекты списка свойств (объекты NSString, NSData, NSArray или NSDictionary), файл, написанный этим методом, можно использовать для инициализации нового массива с помощью метода класса arrayWithContentsOfFile: или метода экземпляра initWithContentsOfFile: , Этот метод рекурсивно проверяет, что все содержащиеся объекты являются объектами списка свойств перед записью файла, и возвращает NO, если все объекты не являются объектами списка свойств, поскольку результирующий файл не будет допустимым списком свойств.

...