“尝试设置非属性列表对象...."带有自定义类的 NSMutableDictionary [英] "Attempt to set a non-property list object...." NSMutableDictionary with custom class

查看:55
本文介绍了“尝试设置非属性列表对象...."带有自定义类的 NSMutableDictionary的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为 ServerModule 的自定义类,它是 NSObject 的子类.我基本上将所有这些 ServerModule 与一个键值对一起存储在 NSMutableDictionary 中.然后将字典存储在 NSUserDefaults 中.我了解到 NSUserDefaults 仅在访问时返回对象的不可变版本,因此我将字典初始化更改为:

I have a custom class called ServerModule which is a subclass of NSObject. I'm basically storing all of these ServerModules with a key-value pair in an NSMutableDictionary. The dictionary is then stored in NSUserDefaults. I learned that NSUserDefaults only returns an immutable version of the object when it is accessed, so I changed my dictionary initialization to this:

_AllModules = [[NSMutableDictionary alloc]initWithDictionary:[_editServerModules objectForKey:@"AllModules"]]; //initialize a copy of AllModules dictionary

现在,我只是想在这个字典中存储一个自定义的 ServerModule 对象,并同步它.以下代码尝试执行此操作:

Now, I am simply trying to store a custom ServerModule object in this dictionary, and sync it. The following code attempts to do this:

//Create new ServerModule
        ServerModule* newServer = [[ServerModule alloc]initWithUUID];
        newServer.name = self.tf_name.text;
        newServer.ip = self.tf_ip.text;
        newServer.port = self.tf_port.text;
        newServer.username = self.tf_user.text;
        newServer.password = self.tf_pass.text;
        //Add the ServerModule to AllModules dictionary with the key of its identifier
        [_AllModules setObject:newServer forKey:newServer.identifier];
        [self updateData];
        [_editServerModules synchronize];

标识符是在ServerModule的构造函数中设置的字符串.这是 updateData 的代码.

The identifier is a string which is set in the constructor of ServerModule. Here is the code for updateData.

[_editServerModules setObject:_AllModules forKey:@"AllModules"];

如果您想知道,@"AllModules" 处的对象在 AppDelegate 中初始化如下:

In case you are wondering, the object at @"AllModules" is initialized in the AppDelegate as follows:

NSMutableDictionary* AllModules = [[NSMutableDictionary alloc]init];

再一次,这是我尝试保存某些内容时遇到的错误:

Once again, here is the error I am getting when I try to save something:

Attempt to set a non-property-list object {
    "42E9EEA0-9051-4E2A-81EA-DC8FC5639C26" = "<ServerModule: 0x8ac4e50>";
} as an NSUserDefaults value for key AllModules

感谢您的帮助!

~Carpetfizz

~Carpetfizz

推荐答案

您只能在 NSUserDefaults.这意味着所有内容,包括任何嵌套的字典值,都必须是属性列表类型.您需要在 ServerModule 对象上实现 NSCoding 协议,然后使用 NSKeyedArchiver 在存储之前序列化您的数据和 NSKeyedUnarchiver 在从 NSUserDefaults.

You can only store property list types (array, data, string, number, date, dictionary) or urls in NSUserDefaults. This means that everything, including any nested dictionary values, must be property list types. You'll want to implement the NSCoding protocol on your ServerModule object and then use NSKeyedArchiver to serialize your data before storing it and and NSKeyedUnarchiver to deflate your data after reading it back out of NSUserDefaults.

例如,假设您显示的属性存在于 ServerModule 对象上,我会添加以下 NSCoding 协议方法到您的 ServerModule 实现:

For example, given the properties you've shown exist on ServerModule objects, I'd add the following NSCoding protocol methods to your ServerModule implementation:

#pragma mark - NSCoding support
-(void)encodeWithCoder:(NSCoder*)encoder {
    [encoder encodeObject:self.name forKey:@"name"];
    [encoder encodeObject:self.ip forKey:@"ip"];
    [encoder encodeObject:self.port forKey:@"port"];
    [encoder encodeObject:self.username forKey:@"username"];
    [encoder encodeObject:self.password forKey:@"password"];
}

-(id)initWithCoder:(NSCoder*)decoder {
    self.name = [decoder decodeObjectForKey:@"name"];
    self.ip = [decoder decodeObjectForKey:@"ip"];
    self.port = [decoder decodeObjectForKey:@"port"];
    self.username = [decoder decodeObjectForKey:@"username"];
    self.password = [decoder decodeObjectForKey:@"password"];
    return self;
}

当然,你还需要序列化:

And then of course you'll need to serialize:

NSData* archivedServerModules = [NSKeyedArchiver archivedDataWithRootObject:_AllModules];
[_editServerModules setObject:archivedServerModules forKey:@"AllModules"];

并适当放气:

NSData* archivedServerModules = [_editServerModules objectForKey:@"AllModules"];
NSDictionary* serverModules = [NSKeyedUnarchiver unarchiveObjectWithData:archivedServerModules];

希望这能让您了解我在说什么.

Hopefully that gives you an idea of what I'm talking about.

这篇关于“尝试设置非属性列表对象...."带有自定义类的 NSMutableDictionary的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆