UserDefaults / KeyedArchiver令人沮丧

时间:2009-12-10 19:03:55

标签: iphone nsmutablearray nsuserdefaults nskeyedarchiver

我正在开发一个家庭作业应用程序,它为每个作业使用自定义Assignment对象。我试图在standardUserDefaults中存储一个NSMutableArray(通过initWithArray :)转换为NSArray,但是我在保存和重新加载数组时遇到了麻烦。

我有一个表视图,您可以从中选择添加新的赋值(加载NewAssignmentViewController)。保存赋值时,它将被推回到AssigmentsViewController中的数组。然后在每次加载显示分配的UITableView时调用它。

以下是相关代码:

-(void)saveToUserDefaults:(NSArray*)myArray{
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];

if (standardUserDefaults) {
    [standardUserDefaults setObject:[NSKeyedArchiver archivedDataWithRootObject:myArray] forKey:@"Assignments"];
    [standardUserDefaults synchronize];
    }
}

-(void)retrieveFromUserDefaults{
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"Assignments"]; 
if (dataRepresentingSavedArray != nil) {
    NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
    if ([oldSavedArray count] != 0) {
        [assignments setArray:[[NSMutableArray alloc] initWithArray:oldSavedArray]];
    }
    else {
        assignments = [[NSMutableArray alloc] initWithCapacity:100];
    }
}
}
 -(void)backButtonPressed {
[self saveToUserDefaults:[[NSArray alloc] initWithArray:assignments]];
[self.navigationController popViewControllerAnimated:YES];
}

请帮忙。它不会加载数组但不会产生任何错误。任何关于UserDefault或KeyedArchiver的提示都会非常感激。

2 个答案:

答案 0 :(得分:2)

这里有几件事:

如果我理解正确,你正在尝试存储一个内容为赋值对象的数组。

如果要将这些对象序列化以存储到NSUserDefaults中,Assignment对象本身需要通过覆盖这些方法来符合NSCoding协议:

- (void)encodeWithCoder:(NSCoder *)encoder;
- (id)initWithCoder:(NSCoder *)decoder;

由于您未发布Assignment对象的代码,因此如果您正确执行此操作或根本不执行此操作,请执行此操作。如果你有,你应该能够编码对象。有关详情,请参阅Archives and Serializations Programming Guide

对于NSUserDefaults,通过我的阅读,您基本上是在尝试将应用程序的对象模型存储在那里。不是最好的主意。 NSUserDefaults最适合与轻量级持久数据一起使用:基本首选项,字符串,通用数据碎片。

我要做的是将您的存档数据写入文件,并在加载视图时加载它。

以下是Beginning iPhone Development关于该主题的一些代码:

  

从符合NSCoding的一个或多个对象创建存档相对容易。首先,我们创建一个NSMutableData实例来保存编码数据,然后创建一个NSKeyedArchiver实例来将对象存档到该NSMutableData实例中:

NSMutableData *data = [[NSMutableData alloc] init]; 
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
  

在创建了这两个之后,我们使用键值编码来存档我们希望包含在存档中的任何对象,如下所示:

[archiver encodeObject:myObject forKey:@”keyValueString”];
  

一旦我们编码了我们想要包含的所有对象,我们就告诉归档器我们已经完成了,将NSMutableData实例写入文件系统,并对我们的对象进行内存清理。

[archiver finishEncoding]; BOOL success = [data writeToFile:@”/path/to/archive” atomically:YES]; 
[archiver release]; 
[data release];
  

要从存档中重构对象,我们会经历类似的过程。我们从存档文件创建一个NSData实例,并创建一个NSKeyedUnarchiver来解码数据:       NSData * data = [[NSData alloc] initWithContentsOfFile:path];       NSKeyedUnarchiver * unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];   之后,我们使用与归档对象相同的密钥从unarchiver中读取对象:

self.object = [unarchiver decodeObjectForKey:@”keyValueString”];

您还需要让application's documents directory保存并加载文件。

这是一本非常有用的书,充满了代码片段。关于持久性的章节可能对你有所帮助。使用Core Data完成此任务可能会更快乐,想一想。

答案 1 :(得分:0)

我不确定这是否能解决您的问题,但您不必将数组从默认值中拉出来作为NSData。检查NSUserDefaults reference,您将看到Arrays是有效的默认对象。