Ios 如何序列化包含NSNull的NSDictionary/NSArray/Property列表(plist)
我想使用Ios 如何序列化包含NSNull的NSDictionary/NSArray/Property列表(plist),ios,objective-c,cocoa,serialization,Ios,Objective C,Cocoa,Serialization,我想使用NSNull将一些空值存储在NSMutableDictionary中,然后使用属性列表序列化这些数据。问题是不允许使用NSNull,并且我得到“属性列表格式无效”错误。有解决办法吗?似乎很奇怪,他们没有将NSNull放在有效的plist对象列表中。不,没有办法将NSNull放在属性列表中。(琐事:二进制属性列表格式实际上支持空值,但编写器不实现支持。) 对于字典,最简单的解决方法是简单地过滤掉空值,这样{foo=“bar”baz=null;}就变成了{foo=“bar”;}。来自NSPr
NSNull
将一些空值存储在NSMutableDictionary
中,然后使用属性列表序列化这些数据。问题是不允许使用NSNull
,并且我得到“属性列表格式无效”错误。有解决办法吗?似乎很奇怪,他们没有将NSNull
放在有效的plist对象列表中。不,没有办法将NSNull
放在属性列表中。(琐事:二进制属性列表格式实际上支持空值,但编写器不实现支持。)
对于字典,最简单的解决方法是简单地过滤掉空值,这样{foo=“bar”baz=null;}就变成了{foo=“bar”;}。来自NSPropertyListSerializationClass的文档: 属性列表对象。plist必须是 一种NSData,NSString,NSNumber, NSDate、NSArray或NSDictionary 对象容器对象也必须 仅包含这些类型的对象
所以你需要一个。根据数据的类型,您可以放入占位符而不是NSNull,然后在加载.plist之前/之后执行一个过程(例如,使用长度为零的NSData对象在plist中表示NSNull)。确切的占位符类型取决于您存储的数据类型,以及选择要避免的内容。然后,加载后,将空NStATTATE转换为NSNull。
而不是使用属性列表,考虑使用NKEKEDAGEVER和NKEKEDUNCHIVFER。属性列表有一组固定的类型,不包括NSNull,也不打算扩展
以下是相关文档的链接:,和。在序列化之前,我将NSArray或NSDictionary转换为NSData。以下是nsarray上用于序列化和反序列化的类别。此ComfortabyBy可处理某些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];
}
说真的,苹果的程序员出了什么问题???我讨厌编写这样的代码。DD,如果您想要的是一般序列化,请使用NSCoder。属性列表有一组固定的类型,因此无论扩展到何种程度,都需要转换某些内容。如果您不喜欢属性列表的限制(如文档所示,属性列表不支持NSNull),则不要使用属性列表。正如另一位评论者所建议的,使用您自己的序列化格式。NSPropertyList支持!=序列化。这与我需要空值来表示键存在但没有相应的值(即,我已经知道有一个键没有数据,而不是我不知道的一个新键)并不完全相同。也许你可以将两者序列化a)一个字典,其中只包含具有相应值的键,和B)所有已知密钥的数组,无论它们是否附加了数据。最终,没有办法直接将NSNull放在plist中,所以您需要找到一个解决方法。非常好!这真是太神奇了(我刚刚验证过),但键控archivers中更常见的方法却没有。Saurabh Wadhwa提供的答案非常好,我自己就用过了,可惜原始海报不存在,无法接受。。。