IOS数据缓存到本地_IOS数据持久化的四种实现方式
在程序开发中、数据层永远是程序的核心结构之一、我们将现实事物进行抽象、使之变成一个个数据、对这些数据的加工处理是代码中能体现技术水平的一大模块、比如数据的请求、解析、缓存、持久化等等
适当的对数据进行持久化存储可以实现应用的离线功能、以此提高用户体验、在iOS开发中、苹果提供了四种持久化方案供我们选择、这些方案分别包括属性列表(plist)、数据归档(NSKeyedValueArchiver/NSUserDefaults)、数据库(sqlite)和coreData等
一、属性列表 plist
属性列表是一种明文的轻量级存储方式、其存储格式有多种、最常规格式为XML格式、在我们创建一个新的项目的时候、Xcode会自动生成一个info.plist文件用来存储项目的部分系统设置、plist只能用数组(NSArray)或者字典(NSDictionary)进行读取、由于属性列表本身不加密、所以安全性几乎可以说为零、因为、属性列表正常用于存储少量的并且不重要的数据
在程序启动后、系统会自动创建一个NSUserDefaults的单例对象、我们可以获取这个单例来存储少量的数据、它会将输出存储在.plist格式的文件中、其优点是像字典一样的赋值方式方便简单、但缺点是无法存储自定义的数据
涉及到的主要类:NSUserDefaults、一般 [NSUserDefaults standardUserDefaults]就够用了
@interface User : NSObject <NSCoding> @property (nonatomic, assign) NSInteger userID; @property (nonatomic, copy) NSString *name; @end
使用方法
1、分开存取
// 存 [[NSUserDefaults standardUserDefaults] setInteger:userID forKey:@”userID”]; [[NSUserDefaults standardUserDefaults] setObject:name forKey:@”name”]; // 取 NSInteger uId = [[[NSUserDefaults standardUserDefaults] integerValueForKey:@”userID”]; NSString *name = [[NSUserDefaults standardUserDefaults] stringForKey:@”name”];
2、按对象存取
// 存 [[NSUserDefaults standardUserDefaults] setObject:self forKey:@”user”]; // 取 User *u = [[NSUserDefaults standardUserDefaults] objectForKey”@”user”];
二、对象归档 NSKeyedValueArchiver/NSUserDefaults
与属性列表相反、同样作为轻量级存储的持久化方案、数据归档是进行加密处理的、数据在经过归档处理会转换成二进制数据、所以安全性要远远高于属性列表、另外使用归档方式、我们可以将复杂的对象写入文件中、并且不管添加多少对象、将对象写入磁盘的方式都是一样的
使用NSKeyedArchiver对自定义的数据进行序列化、并且保存在沙盒目录下、使用这种归档的前提是让存储的数据模型遵守NSCoding协议并且实现其两个协议方法
大部分Object C对象都符合NSCoding协议,也可以在自定义对象中实现NSCoding协议,要实现NSCoding协议,实现两个方法
- (void) encodeWithCoder:(NSCoder *)encoder -(void)initWithCoder:(NSCoder *)encoder
同时、建议对象也同时实现NSCopying协议,该协议允许复制对象,要实现NSCopying协议须实现 -(id)copyWithZone:(NSZone *)zone 方法
@interface User : NSObject <NSCoding> @property (nonatomic, assign) NSInteger userID; @property (nonatomic, copy) NSString *name; @end @implementation User // 以下两个方法一定要实现、不然在调用的时候会crash - (void)encodeWithCoder:(NSCoder *)aCoder; { // 这里放置需要持久化的属性 [aCoder encodeObject:[NSNumber numberWithInteger:self.userID] forKey:@”userID”]; [aCoder encodeObject:self.name forKey:@"name"]; } - (id)initWithCoder:(NSCoder *)aDecoder { if (self = [self init]) { // 这里务必和encodeWithCoder方法里面的内容一致、不然会读不到数据 self.userID = [[aDecoder decodeObjectForKey:@"userID"] integerValue]; self.name = [aDecoder decodeObjectForKey:@"name"]; } return self; }
使用方法
(BOOL)save { NSError *error = nil; // 确定存储路径、一般是Document目录下的文件 NSString* fileName = [self getFileName]; NSString* filePath = [self getFilePath]; if (![[NSFileManager defaultManager] createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:&error]) { NSLog(@”创建用户文件目录失败”); return NO; } return [NSKeyedArchiver archiveRootObject:self toFile:[fileName:userId]]; } @end
三、数据库 sqlite
sqlite是一个轻量级、跨平台的小型数据库、其拥有可移植性高、有着和MySql几乎相同的数据库语句以及无需服务器即可使用的优点
1、可以存储大量的数据、存储和检索的速度非常快
2、能对数据进行大量的聚合、这样比起使用对象来进行这些操作要快
当然、它也具有明显的缺点
1、它没有提供数据库的创建方式
2、它基于C语言框架设计、没有面向对象的API、所以使用起来比较麻烦
3、复杂的数据模型的数据建表相对而言比较麻烦
四、数据库 coreData
coreData是苹果官方iOS5之后推出的综合型数据库、其使用了ORM(Object Relational Mapping)对象关系映射技术、将对象转换成数据、存储在本地数据库中、coreData为了提高效率、甚至将数据存储在不同的数据库中、且在使用的时候将本地数据放到内存中使得访问速度更快
我们可以选择coreData的数据存储方式、包括sqlite、xml等格式、但也正是coreData 是完全面向对象的、其在执行效率上比不上原生的数据库、除此之外、coreData拥有数据验证、undo等其他功能、在功能上是四种持久化方案最多的