IOS开发中数据持久化的几种方法--NSUserDefaults

IOS开发中数据持久化的几种方法--NSUserDefaults

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

 

 

注意事项:

在苹果的官方文档有明确说明:

 

 也就是说,只能存入 NSDataNSStringNSNumberNSDateNSArray, 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值去读取对应的内容。但这样的操作要注意,保存的数据一定是不可变的,不能是可变的数组、可变字符串、可变字典等,否则程序会产生不可预期的错误。

 

posted @ 2016-05-17 20:47  jiwangbujiu  阅读(320)  评论(0编辑  收藏  举报