标签:
IOS 开发中,经常会遇到需要把一些数据保存在本地的情况,那么这个时候我们有以下几种可以选择的方案:

一、使用NSUserDefault是最简单直接的一个办法:
1)保存数据:
1 // 实例化一个NSUserDefaults单例对象 2 NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; 3 // 把一个数组array保存在key为allContact的键值对里 4 [user setObject:array forKey:@"allContact"]; 5 // 直接写入硬盘 6 [user synchronize];
2)读取数据:
1 // 实例化一个NSUserDefaults单例对象 2 NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; 3 // 把保存在里面的array根据key为allContact拿出来 4 NSArray *dataarray = [user objectForKey:@"allContact"];
注意事项:
在苹果的官方文档有明确说明:

也就是说,只能存入 NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. For NSArray and NSDictionary objects, their contents must be property list objects.这些对象,而且(. For NSArray and NSDictionary objects, their contents must be property list objects.)比如数组,字典中存的元素也只能是以上这些对象的内容,那如何把自定义的一个比较复杂的类的实例对象使用NSUserDefaults保存呢?方法如下:
以一个手机联系人类myContact为例说明:
1)在myContact.h文件中让类遵守NSCoding协议:
1 // 2 // myContact.h 3 // 老年人电话本 4 // 5 // Created by mac on 16/5/3. 6 // Copyright © 2016年 mzw. All rights reserved. 7 // 8 9 #import <Foundation/Foundation.h> 10 11 //要使用单例NSUserDefault来存储自定义对象,首先要让自定义的对象遵守NSCoding协议 12 @interface myContact : NSObject<NSCoding> 13 14 @property(nonatomic, copy)NSString *firstname; 15 @property(nonatomic, copy)NSString *lastname; 16 @property(nonatomic, copy)NSString *phoneNumber; 17 @property(nonatomic, copy)NSData *photo; 18 @property(nonatomic, copy)NSString *identify; 19 @property(nonatomic, assign)BOOL emergency; 20 21 @end
2)在myContact.m文件中实现两个方法:encodeWithCoder 和 initWithCoder方法
1 // 2 // myContact.m 3 // 老年人电话本 4 // 5 // Created by mac on 16/5/3. 6 // Copyright © 2016年 mzw. All rights reserved. 7 // 8 9 #import "myContact.h" 10 11 @implementation myContact 12 13 @synthesize firstname; 14 @synthesize lastname; 15 @synthesize phoneNumber; 16 @synthesize photo; 17 @synthesize identify; 18 @synthesize emergency; 19 20 -(void)encodeWithCoder:(NSCoder *)aCoder{ 21 22 [aCoder encodeObject:self.firstname forKey:@"firstname"]; 23 [aCoder encodeObject:self.lastname forKey:@"lastname"]; 24 [aCoder encodeObject:self.phoneNumber forKey:@"phoneNumber"]; 25 [aCoder encodeObject:self.photo forKey:@"photo"]; 26 [aCoder encodeObject:self.identify forKey:@"identify"]; 27 [aCoder encodeBool:self.emergency forKey:@"emergency"];//注意对于布尔类型的不能使用encodeObject,而要对应的使用encodeBool。 28 } 29 30 -(id)initWithCoder:(NSCoder *)aDecoder{ 31 32 if (self = [super init]) { 33 34 self.firstname = [aDecoder decodeObjectForKey:@"firstname"]; 35 self.lastname = [aDecoder decodeObjectForKey:@"lastname"]; 36 self.phoneNumber = [aDecoder decodeObjectForKey:@"phoneNumber"]; 37 self.photo = [aDecoder decodeObjectForKey:@"photo"]; 38 self.identify = [aDecoder decodeObjectForKey:@"identify"]; 39 self.emergency = [aDecoder decodeBoolForKey:@"emergency"];//同理此处要对应的使用decodeBoolForKey。 40 } 41 return self; 42 }
3)完成以上两步,我们就可以通过NSUserDefaults来保存myContact的实例对象了:(以下程序段既涉及到读取,又涉及到追加内容后保存)
1 // 属性值赋值完成后就可以使用NSKeyedArchiver把对象mycontact1打包为一个NSData对象 2 NSData *data = [NSKeyedArchiver archivedDataWithRootObject:mycontact1]; 3 // 创建并初始化一个NSUserDefaults单例对象 4 NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; 5 // 先读取user之前存进去的allContact所对应的值(是一个不可变的数组),然后因为我们要给这个数组追加一个联系人的打包后的NSData数据,所以要把这个数组转换成为一个可变数组。 6 NSMutableArray *contactarray = [NSMutableArray arrayWithArray:[user objectForKey:@"allContact"]]; 7 // 把之前打包好的联系人mycontact1的NSData数据追加到可变数组contactarray中 8 [contactarray addObject:data]; 9 // 再把这个可变数组转换为一个不可变数组 10 NSArray *array = [NSArray arrayWithArray:contactarray]; 11 // 使用相同的key值保存新的array,之前allContact对应的值被替换 12 [user setObject:array forKey:@"allContact"]; 13 // 直接写入硬盘 14 [user synchronize];
注意:通过NSUserDefaults保存的数据是全局的,这也为我们提供了一个管理全局变量的手段,比如在页面A保存了一些数据,在其他很多页面都要用到,那我们可以通过单例来保存,这样就可以在不同的页面中通过同个NSUserDefaults的key值去读取对应的内容。但这样的操作要注意,保存的数据一定是不可变的,不能是可变的数组、可变字符串、可变字典等,否则程序会产生不可预期的错误。
IOS开发中数据持久化的几种方法--NSUserDefaults
标签:
原文地址:http://www.cnblogs.com/jiwangbujiu/p/5503120.html