Я хочу сохранить в NSMutableDictionary
несколько нулевых значений, используя NSNull
, а затем сериализует эти данные, используя список свойств. Проблема NSNull
не разрешена, и я получаю ошибку "Список свойств в недопустимом формате". Есть ли обходной путь для этого? Кажется очень удивительным, что они не помещали NSNull
в список допустимых объектов plist.
Как сериализовать NSDictionary/NSArray/Список свойств (plist), который содержит NSNull
Ответ 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.