“尝试设置非属性列表对象...."带有自定义类的 NSMutableDictionary [英] "Attempt to set a non-property list object...." NSMutableDictionary with custom class
问题描述
我有一个名为 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 ServerModule
s 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屋!