如何使用自定义数据模型将 NSMutableArray 正确传递给 NSUserDefaults?

Posted

技术标签:

【中文标题】如何使用自定义数据模型将 NSMutableArray 正确传递给 NSUserDefaults?【英文标题】:How do I properly pass a NSMutableArray to NSUserDefaults with a custom data model? 【发布时间】:2014-09-25 13:46:54 【问题描述】:

让我先说我的代码被故意隐藏了一点。我知道名字不会好。我正在尝试使用新的 ios 8 功能向我的应用程序添加一个小部件。我正在使用this link as a tutorial

现在,当我的应用程序中调用我的提交按钮时,我的 ViewController 中有这个。到这个时候,我已经把该数组中的所有数据都传递出去了。

//Passes the array of times to the shared group to be called by the notification center widget.
NSUserDefaults *sharedDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.myGroup.TodayExtensionSharingDefaults"];
NSData *encodedArray = [NSKeyedArchiver archivedDataWithRootObject:tableViewController.TimeArray];
[sharedDefaults setObject:encodedArray  forKey:@"TimesArray"];
[sharedDefaults synchronize];

但是,我的数组存储了我创建的自定义数据模型,所以在我的数据模型中我有:

- (void)encodeWithCoder:(NSCoder *)encoder 
    //Encode properties, other class variables, etc
    [encoder encodeInt:_stopNumber forKey:@"stopNumber"];
    [encoder encodeObject:_route forKey:@"route"];
    [encoder encodeObject:_number forKey:@"number"];
    [encoder encodeInt:_time forKey:@"time"];
    [encoder encodeObject:_minutesOrApproaching forKey:@"@minutesOrApproaching"];
    [encoder encodeObject:_noPrediction forKey:@"noPrediction"];


- (id)initWithCoder:(NSCoder *)decoder 
    self = [super init];
    if(self) 
        //decode properties, other class vars
        _stopNumber = [decoder decodeIntForKey:@"stopNumber"];
        _route = [decoder decodeObjectForKey:@"route"];
        _number = [decoder decodeObjectForKey:@"number"];
        _time = [decoder decodeIntForKey:@"time"];
        _minutesOrApproaching = [decoder decodeObjectForKey:@"minutesOrApproaching"];
        _noPrediction = [decoder decodeObjectForKey:@"noPrediction"];
    
    return self;

然后在我的小部件中,我调用了以下代码:

NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"group.myGroup.TodayExtensionSharingDefaults"];
    NSData *myDecodedObject = [defaults objectForKey: @"TimesArray"];
    NSArray *decodedArray =[NSKeyedUnarchiver unarchiveObjectWithData: myDecodedObject];

    int i = 0;
    for (ETA *eta in decodedArray) 
        if(i == 0)
            _stopNumber.text = eta.number;
        
        UILabel *label = [timeSlots objectAtIndex:i];
        label.text = eta.minutesOrApproaching;
        i++;
    

我的问题是我不断收到:

* 由于未捕获的异常“NSInvalidUnarchiveOperationException”而终止应用程序,原因:“*” -[NSKeyedUnarchiver decodeObjectForKey:]:无法解码类对象(ETA)' 在此输入代码

所以我有点不高兴,因为我不知道我在这里做错了什么。如果有人能帮助我指出正确的方向,那就太好了。再次感谢!

【问题讨论】:

您可能不应该使用NSUserDefaults 来存储应用数据。也许使用数据库或自定义数据文件格式。 这不是关于存储一个可变数组,而是关于storing a custom object in NSUserDefaults(或者,在这种情况下,是一个自定义对象数组),不是吗? 是的,但我不确定它是否与可变数组有关。此外,我正在按照教程在我的应用程序的功能部分中使用 AppData 选项。 不,可变数组将被简单地视为普通的NSArray。我看不出任何明显的东西,你的代码对我来说看起来不错。在搜索此消息时,我发现了两个常见问题:缺少符号(忘记添加框架)或一些罕见的链接问题。因此,请尝试从头开始清理和构建(并从设备中删除您的应用)并确保您的小部件确实包含(链接)您的课程。 @meda 是的,我现在正在实施它。我不再收到错误,这很好,但我的标签似乎没有改变,所以我必须弄清楚发生了什么。 【参考方案1】:

因此,传递自定义类可能会很痛苦。尽管所有代码似乎都是正确的,但我仍然收到错误消息。所以我退后一步,看着我的自定义对象并问自己“我真正需要的是什么?”并且使用该过程决定我只需要某些值,因此我只加密了那些值而不是对象。由于这些值是整数和字符串,因此它们内置于 iOS 中以了解如何编码和解码。从那里开始,感谢@meda 的回答和我的想法,我能够传递价值观。

【讨论】:

“加密”和“编码”有很大的区别,也许你的意思是“编码”。

以上是关于如何使用自定义数据模型将 NSMutableArray 正确传递给 NSUserDefaults?的主要内容,如果未能解决你的问题,请参考以下文章

如何将自定义图像输入此模型?

GTK+ 3.0:如何将 Gtk.TreeStore 与自定义模型项一起使用?

如何将使用 Mask Rcnn 在自定义对象检测上创建蒙版图像的 Keras 模型转换为 CoreML 模型以在 iOS 应用程序中使用?

Django 使用自定义 SQL 而不是模型将 JSON 对象返回到模板

Laravel Nova 自定义字段获取模型值

如何将自定义 Pytorch 模型转换为 torchscript(pth 到 pt 模型)?