Как сохранить NSArray с настроенным объектом?

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

[array writeToFile:m_sApplicationPlistPath atomically:YES];

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

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

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

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

4 ответа

Решение

Вы можете заставить это работать, используя методы, определенные в 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 с использованием NSKeyValueCoding метод setValuesForKeysWithDictionary:

+ (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: конвертировать экземпляр на лету.

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

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

NSData *data = NSKeyedArchiver archivedDataWithRootObject:theArray];

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

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

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

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

Другие вопросы по тегам