Подтвердить что ты не робот

Как сериализовать NSDictionary/NSArray/Список свойств (plist), который содержит NSNull

Я хочу сохранить в NSMutableDictionary несколько нулевых значений, используя NSNull, а затем сериализует эти данные, используя список свойств. Проблема NSNull не разрешена, и я получаю ошибку "Список свойств в недопустимом формате". Есть ли обходной путь для этого? Кажется очень удивительным, что они не помещали NSNull в список допустимых объектов plist.

4b9b3361

Ответ 1

Я конвертирую NSArray или NSDictionary в NSData перед сериализацией. Ниже приведена категория nsarray для сериализации и десериализации. Это удобно обрабатывает некоторые данные: nsnull

@implementation NSArray(Plist)

-(BOOL)writeToPlistFile:(NSString*)filename{
    NSData * data = [NSKeyedArchiver archivedDataWithRootObject:self];
    NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString * documentsDirectory = [paths objectAtIndex:0];
    NSString * path = [documentsDirectory stringByAppendingPathComponent:filename];
    BOOL didWriteSuccessfull = [data writeToFile:path atomically:YES];
    return didWriteSuccessfull;
}

+(NSArray*)readFromPlistFile:(NSString*)filename{
    NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString * documentsDirectory = [paths objectAtIndex:0];
    NSString * path = [documentsDirectory stringByAppendingPathComponent:filename];
    NSData * data = [NSData dataWithContentsOfFile:path];
    return  [NSKeyedUnarchiver unarchiveObjectWithData:data];
}

Ответ 2

Вместо использования списка свойств рассмотрите использование NSKeyedArchiver и NSKeyedUnarchiver. Списки свойств имеют фиксированный набор типов и не включают NSNull и не предназначены для расширения.

Вот ссылки на соответствующую документацию: NSCoding, NSKeyedArchiver и NSKeyedUnarchiver.

Ответ 3

Нет, нет способа разместить NSNull в списке свойств. (Trivia: формат списка двоичных свойств фактически поддерживает нули, но писатель не реализует поддержку.)

Для словаря самым легким обходным путем является простое отбрасывание нулевых значений, поэтому {foo = "bar"; baz = null; } становится {foo = "bar"; }.

Ответ 4

Из документации NSPropertyListSerializationClass:

Объект списка свойств. plist должен быть своего рода NSData, NSString, NSNumber, NSDate, NSArray или NSDictionary объект. Контейнерные объекты также должны содержат только такие объекты.

Итак, у вас должен быть один из них. В зависимости от типа данных вы можете помещать заполнитель вместо NSNull, а затем выполнять процесс до/после загрузки .plist(например, используя объект NSData с нулевой длиной для представления вашего NSNull в plist). Именно то, что заполнитель будет зависеть от того, какие данные вы храните, и выбирая что-то, чего следует избегать. Затем, после загрузки, переведите пустой NSData обратно в NSNull.