欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  技术分享

IOS数据缓存到本地_IOS数据持久化的四种实现方式

程序员文章站 2021-12-28 21:39:09
...

在程序开发中、数据层永远是程序的核心结构之一、我们将现实事物进行抽象、使之变成一个个数据、对这些数据的加工处理是代码中能体现技术水平的一大模块、比如数据的请求、解析、缓存、持久化等等

适当的对数据进行持久化存储可以实现应用的离线功能、以此提高用户体验、在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等其他功能、在功能上是四种持久化方案最多的