基本上我使用的是一些名为OrderedDictionary的开源代码,它源自NSMutableDictionary。然后我想通过向OrderedDictionary类添加编码和解码方法将有序字典数据保存到NSUserDefaults。但是,我意识到没有调用编码和解码方法,因此,不再对已解码的字典进行排序。以下是我的代码:
@interface OrderedDictionary : NSMutableDictionary <NSCopying, NSCoding>
{
NSMutableDictionary *dictionary;
NSMutableArray *array;
}
在实施文件中:
/**
* encode the object
**/
- (void)encodeWithCoder:(NSCoder *)coder
{
[super encodeWithCoder:coder];
[coder encodeObject:dictionary forKey:@"dictionary"];
[coder encodeObject:array forKey:@"array"];
}
/**
* decode the object
*/
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self != nil)
{
dictionary = [coder decodeObjectForKey:@"dictionary"];
array = [coder decodeObjectForKey:@"array"];
}
return self;
}
使用它的快速示例代码:
dictionary = [[OrderedDictionary alloc] init];
[dictionary setObject:@"one" forKey:@"two"];
[dictionary setObject:@"what" forKey:@"what"];
[dictionary setObject:@"7" forKey:@"7"];
NSLog(@"Final contents of the dictionary: %@", dictionary);
if ([[NSUserDefaults standardUserDefaults] objectForKey:@"myDictionary"] == nil)
{
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:dictionary]
forKey:@"myDictionary"];
}
else
{
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *savedDictionary = [currentDefaults objectForKey:@"myDictionary"];
if (savedDictionary != nil)
{
OrderedDictionary *oldData = [NSKeyedUnarchiver unarchiveObjectWithData:savedDictionary];
if (oldData != nil)
{
NSLog(@"Final contents of the retrieved: %@", oldData);
}
}
}
问题是,最终的retrieveDictionary没有原始数据顺序,并且根本没有调用编码和解码方法。
提前感谢您的帮助! :)
答案 0 :(得分:4)
有一个名为-classForCoder
的NSObject方法需要在OrderedDictionary中覆盖。来自文档:
classForCoder
在编码期间被子类重写以替换除其自己之外的类。- (类)classForCoder
返回值
在编码期间替换接收者自己的类的类。讨论
NSCoder调用此方法。 NSObject中的 实现返回接收者的类。私有子类 类集群替换其公共超类的名称时 正在存档。
最后一行是关键。所以,在OrderedDictionary.m中:
- (Class)classForCoder
{
return [self class]; // Instead of NSMutableDictionary
}
此外,如果您不使用ARC,请确保保留从-decodeObjectForKey
返回的对象。正如rob mayoff在下面提到的,你不应该致电[super initWithCoder:]
(或[super encodeWithCoder:'
)。我还改变了关键字符串以避免碰撞。
- (id)initWithCoder:(NSCoder *)coder
{
if (self != nil)
{
dictionary = [[coder decodeObjectForKey:@"OrderedDictionary_dictionary"] retain];
array = [[coder decodeObjectForKey:@"OrderedDictionary_array"] retain];
}
return self;
}
答案 1 :(得分:0)
您可能使用错误的初始化程序OrderedDictionary
创建新的initWithDictionary:
。试试这个:
OrderedDictionary *oldData = [NSKeyedUnarchiver unarchiveObjectWithData: savedDictionary];
if (oldData != nil)
{
NSLog(@"Final contents of the retrieved: %@", oldData);
}
确保initWithDictionary:
期望OrderedDictionary
作为参数。我的猜测是它需要一个NSDictionary
。
编辑:保存默认值的代码应包含以下内容:
OrderedDictionary *myDict = ...;
NSData* data = [NSKeyedArchiver archivedDataWithRootObject: myDict];
[[NSUserDefaults standardDefaults] setObject: data forKey: @"myDictionary"];