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

How to save and retrieve NSObject class using NSUserDafaults in iOS

您好,我想使用 NSUserDefaults 保存和检索 NSObject class,因为我写了下面的代码,但出现如下异常

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object for key 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);

模型类:-

.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];

对于自定义 class,您必须在 bean class:

中编辑此方法
- (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 class。这是一个非常简单而强大的工具。

来自 Jayesh Thanki 的好回答,我尝试了这个 question.I 中的示例,然后是您的 coding.First 我尝试了直接保存和检索而不使用编码器和解码器方法。

保存

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:]: unrecognized selector sent to instance 0x7fc65940fc40

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SavingBean encodeWithCoder:]: unrecognized selector sent to instance 0x7fc65940fc40'

然后我用谷歌搜索了大部分答案

The NSCoding protocol declares the two methods that a class must implement so that instances of that class can be encoded and decoded. This capability provides the basis for archiving (where objects and other structures are stored on disk) and distribution (where objects are copied to different address spaces).

encodeWithCoder

encodeWithCoder: instructs the object to encode its instance variables to the coder provided; an object can receive this method any number of times.

initWithCoder

initWithCoder: instructs the object to initialize itself from data in the coder provided; as such, it replaces any other initialization method and is sent only once per object.

然后我明白了我们必须首先在 NSObject 中实现 encodeWithCoder 和 inintWithCoder Class.After 只有我们应该保存和检索数据。

->encoder is an archiver object
->decoder is an unarchiver object

现在首先我们必须在 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];

现在,当我 运行 应用程序时,它不显示任何 error.It 现在工作正常。

为什么我在这里给出这些东西是如果有人在某些情况下看到并尝试这个答案,他们可能会得到像 above.So 这样的错误,如果他们更喜欢这个问题的两个答案,他们可以很容易地理解并得到解决方案很简单。

encodeWithCoder and initWithCoder of NSCoding