如何在iOS中使用NSUserDafaults保存和检索NSObject类

您好我想保存和检索使用NSUserDefaults NSObject类为我写下面的代码,但我得到像下面的exception

由于未捕获exception“ 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 

你可以像这样设置对象:

 NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults]; NSData *data = [NSKeyedArchiver archivedDataWithRootObject:savingbean]; [currentDefaults setObject:data forKey:@"DATA"]; [currentDefaults synchronize]; 

并获得像这样的对象:

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

这里是大多数投票相似的答案。 你也可以从那里得到好东西。

您也可以使用JSON加速器来创buildbean类。 这是非常简单而强大的工具。

从Jayesh Thanki的良好答案我试着从这个问题的样本。我跟着你的编码。首先,我试着直接保存和检索没有编码器和解码器的方法。

保存

 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:]:无法识别的select器发送到实例0x7fc65940fc40

由于未捕获的exception“NSInvalidArgumentException”而终止应用程序,原因:' – [SavingBean encodeWithCoder:]:无法识别的select器发送到实例0x7fc65940fc40'

然后我search了大部分答案

NSCoding协议声明了一个类必须实现的两个方法,以便该类的实例可以被编码和解码。 此function为归档(其中对象和其他结构存储在磁盘上)和分发(将对象复制到不同的地址空间)提供了基础。

encodeWithCoder

encodeWithCoder:指示对象将其实例variables编码到所提供的编码器; 一个对象可以多次接收这个方法。

的initWithCoder

initWithCoder:指示对象从提供的编码器中的数据初始化自己; 因此,它取代了其他的初始化方法,每个对象只发送一次。

然后我明白,我们必须先在NSObject类中实现encodeWithCoder和inintWithCoder,然后才能保存和检索数据。

– > 编码器是一个归档器对象
– > 解码器是一个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]; 

现在,当我运行该应用程序,它不显示任何错误。它现在工作正常。

为什么我在这里给这些东西是如果有人看到和尝试这个答案,在某些情况下,他们可以得到上述的错误。所以如果他们喜欢这个问题的两个答案,他们可以很容易地理解和得到解决scheme很简单。

encodeWithCoder和NSWoding的initWithCoder