用户默认值/KeyedArchiver 挫败感

发布于 2024-08-14 11:20:25 字数 1417 浏览 4 评论 0原文

我正在开发一个作业应用程序,该应用程序为每个作业使用自定义作业对象。我试图在 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 一般的提示将不胜感激。

I'm working on a homework app that uses custom Assignment objects for each assignment. I am trying to store an NSMutableArray (casted to an NSArray via initWithArray:) in standardUserDefaults but I'm having trouble with saving and reloading the array.

I have a table view from which you can choose to add a new assignment (which loads NewAssignmentViewController). When you save the assignment, it is pushed back to an array in AssigmentsViewController. And then you call it every time you load the UITableView which shows the assignments.

Here is the relating code:

-(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];
}

Please help. It does not load the array but does not give any error. Any tips about UserDefault or KeyedArchiver in general would be greatly appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

吹泡泡o 2024-08-21 11:20:25

这里有几件事:

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

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

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

由于您没有发布赋值对象的代码,所以不知道您是否正确执行了此操作或根本没有执行此操作。如果你有,你应该能够对对象进行编码。请参阅 档案和序列化编程指南了解更多信息。

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

我要做的是将存档数据写到一个文件中,并在加载视图时加载它。

以下是开始 iPhone 开发中关于该主题的一些代码:

从一个或多个符合 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];
之后,我们使用与归档对象相同的密钥从解归档器中读取对象:

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

您还需要获取您的 应用程序的文档目录,用于保存和加载文件。

这是一本非常有用的书,充满了代码片段。关于坚持的章节可能对你有帮助。想想看,您可能会更高兴使用 Core Data 来完成此任务。

Couple of things here:

If I understand you correctly, you're trying store an array whose contents are the assignment objects.

If you want to serialize these objects for storage into NSUserDefaults, the Assignment objects themselves need to conform the NSCoding protocol by overriding these methods:

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

Since you didn't post the code for your Assignment objects, dunno if you did this properly or at all. If you have you should be able to encode the object. See the Archives and Serializations Programming Guide for more.

As for NSUserDefaults, by my read, you're basically trying to store your application's object model there. Not the best idea. NSUserDefaults is best suited for use with light-weight persistent data: basic preferences, strings, scraps of universal data.

What I would do is write out your archived data to a file and load it when your view loads.

Here's some code from Beginning iPhone Development on that subject:

Creating an archive from an object or objects that conforms to NSCoding is relatively easy. First, we create an instance of NSMutableData to hold the encoded data and then create an NSKeyedArchiver instance to archive objects into that NSMutableData instance:

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

After creating both of those, we then use key-value coding to archive any objects we wish to include in the archive, like this:

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

Once we’ve encoded all the objects we want to include, we just tell the archiver we’re done, write the NSMutableData instance to the file system, and do memory cleanup on our objects.

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

To reconstitute objects from the archive, we go through a similar process. We create an NSData instance from the archive file and create an NSKeyedUnarchiver to decode the data:
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
After that, we read our objects from the unarchiver using the same key that we used to archive the object:

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

You'd also need to get your application's documents directory to save and load the files.

It's a wildly useful book, full of drop in code snippets. The chapter on persistence might be helpful for you. You might be much happier using Core Data for this task, come to think of it.

蓝戈者 2024-08-21 11:20:25

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

I'm not sure if this will fix your problem, but you don't have to pull the array out of Defaults as NSData. Check the NSUserDefaults reference and you'll see that Arrays are valid default objects.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文