您好我想使用NSObject
保存并检索NSUserDefaults
类,因为我在下面的代码中写了但是我得到如下的异常
由于未捕获的异常“
NSInvalidArgumentException
”而终止应用,原因:'尝试为密钥DATA插入非属性列表对象'
保存: -
SavingBean*savingbean = [[SavingBean alloc]init];
[savingbean savingData:userName.text :passWord.text];
NSUserDefaults * defaults = [[NSUserDefaults alloc]init];
[defaults setObject:savingbean forKey:@"DATA"];
用于检索: -
defaults = [[NSUserDefaults alloc]init];
savingbean = [defaults objectForKey:@"DATA"];
NSLog(@"Username is===>%@",savingbean.userName);
NSLog(@"Password is===>%@",savingbean.passWord);
ModelClas: -
.h文件: -
#import <Foundation/Foundation.h>
@interface SavingBean : NSObject{
NSString *userName;
NSString *passWord;
}
@property(nonatomic, retain) NSString *userName;
@property(nonatomic, retain) NSString *passWord;
-(void)savingData :(NSString*)userName :(NSString*)password;
@end
.m文件: -
#import "SavingBean.h"
@implementation SavingBean
@synthesize userName,passWord;
-(void)savingData :(NSString*)username :(NSString*)password{
userName = username;
passWord = password;
}
@end
答案 0 :(得分:8)
您可以像这样设置对象:
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:savingbean];
[currentDefaults setObject:data forKey:@"DATA"];
[currentDefaults synchronize];
并且对于这样的get对象:
NSData *data = [currentDefaults objectForKey:@"DATA"];
SavingBean *token = [NSKeyedUnarchiver unarchiveObjectWithData:data];
对于Custom类,您必须在bean类中编辑此方法:
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:self.userName==nil?@"":self.userName forKey: @"userName"];
[encoder encodeObject:self.passWord==nil?@"":self.passWord forKey: @"passWord"];
}
-(id)initWithCoder:(NSCoder *)decoder
{
self = [super init];
if(self)
{
self.userName = [decoder decodeObjectForKey: @"userName"];
self.passWord = [decoder decodeObjectForKey: @"passWord"];
}
return self;
}
Here是投票最多的类似答案。你也可以从那里得到好东西。
您还可以使用JSON Accelerator创建bean类。这是一个非常简单而强大的工具。
答案 1 :(得分:1)
从Jayesh Thanki的好答案我尝试了这个问题的样本。我跟着你的编码。首先我尝试了直接使用Save and Retrieve而没有编码器和解码器方法。
保存
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:savingbean];
[currentDefaults setObject:data forKey:@"DATA"];
[currentDefaults synchronize];
用于检索
NSData *data = [currentDefaults objectForKey:@"DATA"];
savingbean = [NSKeyedUnarchiver unarchiveObjectWithData:data];
现在显示错误
[SavingBean encodeWithCoder:]:无法识别的选择器发送到实例0x7fc65940fc40
由于未捕获的异常终止应用程序&#39; NSInvalidArgumentException&#39;,原因:&#39; - [SavingBean encodeWithCoder:]:无法识别的选择器发送到实例0x7fc65940fc40&#39;
然后我用Google搜索了大部分答案
NSCoding协议声明了类必须实现的两种方法,以便可以对该类的实例进行编码和解码。此功能为归档(对象和其他结构存储在磁盘上)和分发(将对象复制到不同的地址空间)提供了基础。
<强> encodeWithCoder 强>
encodeWithCoder:指示对象将其实例变量编码为提供的编码器;对象可以多次接收此方法。
<强>的initWithCoder 强>
initWithCoder:指示对象从提供的编码器中的数据初始化自身;因此,它取代了任何其他初始化方法,并且每个对象只发送一次。
然后我明白我们必须首先在NSObject类中实现encodeWithCoder和inintWithCoder。之后我们只能保存和检索数据。
- &gt; 编码器是一个归档对象
- &gt; decoder是一个unarchiver对象
现在首先我们必须在SavingBean.m中实现encodeWithCoder和initWithCoder
- (void)encodeWithCoder:(NSCoder *)encoder
{
//Encode properties, other class variables, etc
[encoder encodeObject:@"AbhiRam" forKey:@"username"];
[encoder encodeObject:@"Test@123" forKey:@"password"];
}
- (id)initWithCoder:(NSCoder *)decoder
{
if((self = [super init]))
{
//decode properties, other class vars
userName = [decoder decodeObjectForKey:@"username"];
passWord = [decoder decodeObjectForKey:@"password"];
}
return self;
}
然后在ViewController.m
中保存
SavingBean *savingbean = [[SavingBean alloc]init];
NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:savingbean];
[currentDefaults setObject:data forKey:@"DATA"];
[currentDefaults synchronize];
用于检索
NSData *data = [currentDefaults objectForKey:@"DATA"];
savingbean = [NSKeyedUnarchiver unarchiveObjectWithData:data];
现在,当我运行应用程序时,它没有显示任何错误。现在工作正常。
为什么我在这里提供这些东西是如果有人在某些情况下看到并尝试这个答案他们可以得到如上所述的错误。所以如果他们更喜欢这个问题的两个答案,他们可以很容易地理解并且非常简单地得到解决方案。 / p>