iOS数据持久化 NSUserDefaults的使用

在iPhone中,想要在本地存储数据有三种方法:数据库,文件,还有NSUSerDefault,NSUserDefault是系统自定义的类,可以随时在需要使用的地方声明对象然后存储数据。无需添加协议。NSUserDefault与文件和数据库相比也有自身的限制,能存储的文件内容较少,不能放置大容量数据。

声明方法很简单:

NSUserDefaults *myDefault =[NSUserDefaults standardUserDefaults];
然后可以用setObject:forKey:方法往NSUserDefault中存数据,objectForKey:方法取数据,例如:

- (void)viewDidLoad
{
    NSUserDefaults *myDefault =[NSUserDefaults standardUserDefaults];//声明
    NSString *dataString =@"helloWorld";
    [myDefault setObject:dataString forKey:@"data"];//存数据
    NSString *dataStringSec = [[NSUserDefaults standardUserDefaults] objectForKey:@"data"];//取数据
    NSLog(@"%@",dataStringSec);
}
NSUserDefault可以存放非自定义类型数据,只支持 :NSString, NSNumber, NSDate, NSArray, NSDictionary。也许会有个疑问,我把数据自定义数据放在数组里存进去不就可以了吗?答案是否定的。要存放自定义的数据,必须经过NSCoder对象编码和解码。

NSCoder编码和解码是cocoa自身的一种机制,当你的数据要写入硬盘中去的时候,数据就会进行编码变成二进制文件写入硬盘中,当你要读出硬盘上的数据时,数据就会进行解码,这两个过程分别是序列化和反序列化。因为非自定义类型数据例如NSString,NSData等等自身已经隐含了<NSCoding>协议,即进行了对象的序列化与反序列化,我们可以直接把数据存放到NSUserDefaults与plist文件中。所以我们现在要做的事情就是给自定义的类添加NSCoder协议。

首先声明了一个People类

People.h

#import <Foundation/Foundation.h>

@interface People : NSObject<NSCoding>
@property(strong,nonatomic)NSString *name;
@property(assign,nonatomic)NSInteger age;
@property(assign,nonatomic)Boolean isMale;
-(void) initwithname:(NSString *)n andage:(NSInteger)a andisMale:(Boolean)i;
@end
People.m

#import "People.h"

@implementation People
@synthesize name;
@synthesize age;
@synthesize isMale;
-(void) initwithname:(NSString *)n andage:(NSInteger)a andisMale:(Boolean)i{
        self.name=n;
        self.age=a;
        self.isMale=i;
}
-(void)encodeWithCoder:(NSCoder *)aCoder//编码
{
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeInteger:self.age forKey:@"age"];
    [aCoder encodeBool:self.isMale forKey:@"isMale"];
}

- (id)initWithCoder:(NSCoder *)aDecoder//解码
{
    self = [super init];
    if (self)
    {
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.age = [aDecoder decodeIntegerForKey:@"age"];
        self.isMale =[aDecoder decodeBoolForKey:@"isMale"];
    }
    return self;
}
@end

一般的NSString用到的是encodeObject:ForKey:方法,NSInteger 要用到encodeInteger:forKey:方法,而boolean/BOOL则要用到encodeBool:ForKey:方法,要注意区分。

ViewController.h

#import <UIKit/UIKit.h>
#import "People.h"
@interface ViewController : UIViewController<NSCoding>
@property(strong,nonatomic)People *people;
@end

最重要的是要加入<NSCoding>委托

ViewController.m

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize people;
- (void)viewDidLoad
{
    people=[[People alloc]init];
    [people initwithname:@"change" andage:20 andisMale:true];
    NSData *archivePeopleData = [NSKeyedArchiver archivedDataWithRootObject:people];
    NSUserDefaults *myDefault =[NSUserDefaults standardUserDefaults];
    [myDefault setObject:archivePeopleData forKey:@"people"];
    People *Secpeople =[[People alloc]init];
    NSData *myEncodedObject = [[NSUserDefaults standardUserDefaults] objectForKey:@"people"];
    Secpeople = [NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
    NSLog(@"name=%@,age=%d,isMale=%@",Secpeople.name,Secpeople.age,Secpeople.isMale?@"true":@"false");

}
@end

其中要通过NSData作为载体传输数据,即使在自定义类中做好了NSCoding,直接把自定义类加进NSUserDefaults中还是会报错
     NSData *archivePeopleData = [NSKeyedArchiver archivedDataWithRootObject:people];
     Secpeople = [NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
这两句分别是编码和解码的过程。

至此,关于NSUSerDefaults的介绍就结束了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值