在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; @endPeople.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
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 *archivePeopleData = [NSKeyedArchiver archivedDataWithRootObject:people];
Secpeople = [NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];这两句分别是编码和解码的过程。
至此,关于NSUSerDefaults的介绍就结束了。