iOS—持久化的几种方案

数据持久化

iOS中的永久存储,也就是在关机重新启动设备,或关闭应用时不会丢失数据。在实际开发中,往往需要持有存储数据的。

数据持有化的目的

  • 快速展示,提升体验
    • 已经加载过的数据,用户下次查看的时候,不需要再次从网络(磁盘)加载,直接展示给用户
  • 节省用户流量(节省服务器资源)
    • 对于较大的资源数据进行缓存,下次展示无需下载消耗流量
    • 同时降低了服务器的访问次数,节约服务器资源
  • 离线使用
  • 记录用户操作

数据持有化方式分类

在移动端的数据持有化方式总体有两类

内存缓存
  • 定义: 对于使用频率比较高的数据,从网络或磁盘加载数据到内存以后,使用后并不马上销毁,下次使用直接从内存加载。
    内存指当前程序的运行空间,缓存速度快容量小,是临时存储文件用的,供CPU直接读写。打开一个程序,他是在内存中存储,关闭程序后内存就又回到原来的空间空间。
  • 案例
    • iOS系统图片加载——[UIImage imageNamed:@“imageName”]
    • 网络图片加载三方库 SDWebImage
磁盘缓存
  • 定义:将从网络加载的,用户操作产生的数据写入到磁盘,用户下次查看、继续操作时,直接从磁盘加载使用
    磁盘是程序的存储空间,缓存容量大、速度慢、可持有化。与内存不同的是磁盘是永久存储东西的。
  • 案例
    用户输入内容草稿缓存
    搜索历史缓存
    网络图片加载三方库 SDWebImage

沙盒

iOS每个应用程序在安装时,会创建属于自己的沙盒文件(存储空间)。应用程序只能访问自身的沙盒文件,不能访问其他应用程序的沙盒文件。所有非代码文件都要保存在此,例如属性文件plist、文本文件、图像、图标、媒体资源等,其原理是通过重定向技术,把程序生成和修改的文件定向到自身文件夹中。

每个app的沙盒下面都有相似目录结构
在这里插入图片描述
获取应用程序沙盒路径
NSString *path = NSHomeDirectory();

模拟机沙盒路径
在这里插入图片描述

注意:每次编译代码会生成新的沙盒路径,注意是编译不是启动,所以模拟机或者真机运行,每次运行所得到的沙盒路径都是不一样的,线上版本app真机不会生成新的沙盒路径

上面的路径就是当前应用程序目录的路径,该目录下就是应用程序的沙盒,在该目录下有四个文件夹:Documents、Library、SystemData、tmp,当前应用程序只能访问该目录下的文件。

访问沙盒目录常用的方法

FOUNDATION_EXPORT NSArray<NSString *> *NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde);

该方法返回一个数组,在iphone中由于只有一个唯一路径,元素只有一个,所以直接取数组第一个元素即可

  • 参数1 directory:指定搜索的目录名称,比如使用NSDocumentDirectory表明我们要搜索的时Document目录。如果换成NSCachesDirectory就表明我们搜索的是Library/Caches目录
    NSSearchPathDirectory枚举值部分如下
    在这里插入图片描述
  • 参数2 domainMask:NSSearchPathDomainMask类型,搜索主目录的位置,NSUserDomainMask表示搜索的范围限制于当前应用沙盒目录。NSLocalDomainMask(表示/Library)
    在这里插入图片描述
  • 参数3 expandTilde:是否获取完整路径,在iOS中全写形式是/User/userName,该值为yes表示全写形式,为no就直接写成~
    在这里插入图片描述

现在分别介绍沙盒下的目录
在这里插入图片描述

  • Documents
    保存持有化数据,会备份。一般用来存储需要持有化的数据
    一般在项目中,我们会把一些用户的登录信息以及搜索历史等关键数据存储到这里。
    不能存放缓存文件,否则上架不被通过
    此文件夹是默认备份的,备份到iCloud
    NSString *docStr = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
  • Library
    获取Library路径
    NSString *libStr = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject];
    在这里插入图片描述
    • Caches
      存放体积大又不需要备份的数据
      缓存数据应该保存在/Library/Caches目录下
      缓存数据在设备低存储空间时可能会被删除,iTunes或iCloud不会对其进行备份。
    • Perferences
      保存应用的所有偏好设置,iCloud会备份设置信息。需要通过NSUserDefault这个类来访问应用程序的偏好设置
      在这里插入图片描述
  • tmp
    临时文件夹,临时数据保存在这里,不会被备份。保存应用运行时所需的临时数据,系统会自动清理。
    在这里插入图片描述

持久化方式

  • NSUserDefaults
    简单数据快速读写,不能存储自定义类型
    UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘应用程序就终止了。出现以上问题,可以通过调用synchornize方法[defaults synchornize];强制写入。
    偏好设置存储的优点:
    不需要关心文件名,系统会自动帮你生成一个文件名
    快速做键值对的存储
    在这里插入图片描述
  • Property list (属性列表)文件存储
    属性列表是一种XML格式的文件,拓展名为plist如果对是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,就可以使用writeToFile:atomically:方法直接将对象写到属性列表文件中。
    在这里插入图片描述
    在这里插入图片描述
  • 对象的归档、解档
    NSKeyedArchiver如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,可以直接用NSKeyedArchiver进行归档和恢复。
    在这里插入图片描述
    不是所有的对象都可以直接用这种方法进行归档,只有遵守了NSCoding协议的对象才可以。NSSecureCoding也遵循了原来NSCoding这个协议,我们还需要遵实现NSSecureCoding的supportsSecureCoding方法
    • NSCoding协议的2个方法
      encodeWithCoder:每次归档对象时,都会调用这个方法。一般在这个方法里面指定如何归档对象中的每个实例变量,可以使用encodeObject:forKey:方法归档实例变量
      initWithCoder:每次从文件中恢复(解码)对象时,都会调用这个方法。一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forKey方法解码实例变量。
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Person : NSObject <NSSecureCoding>

@property (nonatomic, copy) NSString *str;
@property (nonatomic, copy) NSString *name;

@end

#import "Person.h"

@implementation Person

- (void)encodeWithCoder:(NSCoder *)coder {
    [coder encodeObject:self.name forKey:@"name"];
    [coder encodeObject:self.str forKey:@"str"];
}

- (instancetype)initWithCoder:(NSCoder *)coder {
    self.name = [coder decodeObjectForKey:@"name"];
    self.str = [coder decodeObjectForKey:@"str"];
    
    return self;
}

+ (BOOL)supportsSecureCoding {
    return YES;
}

@end

在这里插入图片描述
在对集合进行完全深复制时,也可以使用归档解档的方法
在这里插入图片描述

  • 数据库存储
    • SQLite
      是目前主流的嵌入式关系型数据库,其最主要的特点就是轻量级、跨平台,当前很多嵌入式操作系统都将其作为数据库首选。
    • CoreData
      CoreData是iOS5之后才出现的一个框架,本质上是对SQLite的一个封装,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象,在这个过程中不需要手动编写任何SQL语句,CoreData封装了数据库的操作过程,以及数据库中数据和OC对象的转换过程。通过CoreData管理应用程序的数据模型,可以极大程度减少需要编写的代码数量
    • FMDB
      是一个处理数据存储的第三方框架,框架是对sqlite的封装,整个框架非常轻量级但又不失灵活性,而且更加面向对象。

什么是序列化和反序列化,用来做什么

  • 序列化:把对象转化为字节序列的过程
  • 反序列:化把字节序列恢复成对象
  • 作用:把对象写到文件或者数据库中,并且读取出来

参考
参考
参考
参考

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值