【iOS】—— 持久化
文章目录
- 数据持久化的目的
- iOS中数据持久化方案
- 数据持久化方式分类
- 内存缓存
- 磁盘缓存
- 沙盒机制
- 获取应用程序的沙盒路径
- 沙盒目录的获取方式
- 持久化数据存储方式
- XML属性列表
- Preferences偏好设置(UserDefaults)
- 数据库存储
- 什么是序列化和反序列化,用来做什么?
- 写入和读取plist文件
数据持久化的目的
- 快速展示,提升体验
-
- 已经加载过的数据,用户下次查看时,不需要再次从网络(磁盘)加载,直接展示给用户
- 节省用户流量(节省服务器资源)
-
- 对于较大的资源数据进行缓存,下次展示无需下载消耗流量
-
- 同时降低了服务器的访问次数,节约服务器资源。
- 离线使用
-
- 用户浏览过的数据无需联网,可以再次查看。
-
- 部分功能使用解除对网络的依赖。(百度离线地图、图书阅读器)
-
- 无网络时,允许用户进行操作,等到下次联网时同步到服务端。
- 记录用户操作
-
- 草稿:对于用户需要花费较大成本进行的操作,对用户的每个步骤进行缓存,用户中断操作后,下次用户操作时直接继续上次的操作。
-
- 已读内容标记缓存,帮助用户识别哪些已读。
-
- 搜索记录缓存
iOS中数据持久化方案
NSUserDefault简单数据快速读写Property list(属性列表)文件存储Archiver(归档)SQLite本地数据库CoreData
数据持久化方式分类
在移动端的数据持有化方式总体有两类:
内存缓存
- 定义: 对于使用频率比较高的数据,从网络或磁盘加载数据到内存以后,使用后并不马上销毁,下次使用直接从内存加载。
内存指当前程序的运行空间,缓存速度快容量小,是临时存储文件用的,供CPU直接读写。打开一个程序,他是在内存中存储,关闭程序后内存就又回到原来的空间空间。
- 案例:
-
- iOS系统图片加载 —— [UIImage imageNamed:@“imageName”]
-
- 网络图片加载三方库 SDWebImage
磁盘缓存
- 定义:将从网络加载的,用户操作产生的数据写入到磁盘,用户下次查看、继续操作时,直接从磁盘加载使用
磁盘是程序的存储空间,缓存容量大、速度慢、可持有化。与内存不同的是磁盘是永久存储东西的。
- 案例:
-
- 用户输入内容草稿缓存
-
- 搜索历史缓存
-
- 网络图片加载三方库 SDWebImage
沙盒机制
每个iOS应用都有自己的应用沙盒,应用沙盒就是文件系统目录,与其他应用的文件系统隔离, iOS系统不允许访问其他应用的应用沙盒。在iOS8中已经开放访问(extension)。extension是iOS8新开放的一种对几个固定系统区域的扩展机制,它可以在一定程度上弥补iOS的 沙盒机制对应用间通信的限制。
应用沙盒一般包括以下几个文件目录:应用程序包、Documents、Libaray(下面有Caches和 Preferences目录)、tmp。
应用程序包:包含所有的资源文件和可执行文件。Documents:保存应用运行时生成的需要持久化的数据,iTunes会自动备份该目录。苹果建议将程 序中建立的或在程序中浏览到的文件数据保存在该目录下,iTunes备份和恢复的时候会包括此目 录tmp:保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行 时,系统也有可能会清除该目录下的文件,iTunes不会同步该目录。iphone重启时,该目录下的 文件会丢失。Library:存储程序的默认设置和其他状态信息,iTunes会自动备份该目录。-
Libaray/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除。一 般存放体积比较大,不是特别重要的资源。
-
Libaray/Preferences:保存应用的所有偏好设置,iOS的Settings(设置)应用会在该目录中查找 应用的设置信息,iTunes会自动备份该目录。
获取应用程序的沙盒路径
// 获取沙盒根目录路径
NSString *path = NSHomeDirectory();
注意: 每次编译代码会生成新的沙盒路径,注意是编译不是启动,所以模拟机或者真机运行,每次运行所得到的沙盒路径都是不一样的,线上版本app真机不会生成新的沙盒路径。
上面的代码得到的就是当前应用程序目录的路径,该目录下就是应用程序的沙盒,在该目录下有4个文件夹:Documents、Library、SystemData、tmp,当前应用程序只能访问该目录下的文件。
沙盒目录的获取方式
//获取沙盒根路径
NSString *path = NSHomeDirectory();
NSLog(@"沙盒根路径:%@", path);
//Document路径
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
NSLog(@"Document目录路径:%@", docDir);
// 获取Library的目录路径
NSString *libDir = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) lastObject];
NSLog(@"Libarary目录路径:%@", libDir);
// 获取Caches目录路径
NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
NSLog(@"Cacheas目录路径:%@", cachesDir);
// library Preference
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSLog(@"偏好设置目录路径:%@", defaults);
// 获取tmp目录路径
NSString *tmpDir = NSTemporaryDirectory();
NSLog(@"tmp目录路径:%@", tmpDir);
输出结果:

持久化数据存储方式
XML属性列表
属性列表是一种XML格式的文件,拓展名为plist。
如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,就可以使用
writeToFile:atomically:方法直接将对象写到属性列表文件中,举例说明:
// 获取 Document 文件目录NSString *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];// 在 Document 目录下新建一个 test.plist 文件NSString * filePath = [docPath stringByAppendingPathComponent:@"test.plist"];// 存字典,将字典数据存到刚才的 test.plist 文件NSDictionary* dict = @{ @"name" :@"zxb10", @"age" : @"20" };[dict writeToFile:filePath atomically:YES];// 取字典,从刚才的 test.plist 文件中取出字典数据NSDictionary* dictA = [NSDictionary dictionaryWithContentsOfFile:filePath];NSLog(@"%@", dictA);// 存数组NSArray* array = @[@"zxb10", @"20"];[array writeToFile:filePath atomically:YES];// 取数组NSArray* arrayA = [NSArray arrayWithContentsOfFile:filePath];NSLog(@"%@", arrayA);
输出结果:

我们可以在document目录下找到这个文件:

因为我们最后是存储的 NSArray 数据类型的,所以他这里也就是 NSArray 类型的数据。
Preferences偏好设置(UserDefaults)
很多iOS应用都支持偏好设置,提供了一套标准的解决方案来为应用加入偏好设置功能,比如保存用户名,字体大小,密码,是否自动登录等。
每个应用都有个NSUserDefaults实例,可以通过它来存取偏好设置,不需要路径。其本身的创建类似于单例模式,我们在后面用不同的属性名再次申请创建,会覆盖之前的数据。
NSUserDefaults:简单数据快速读写,不能存储自定义类型。
UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘应用程序就终止了。出现以上问题,可以通过调用synchornize方法[defaults synchornize];强制写入。
偏好设置存储的优点:
- 不需要关心文件名,系统会自动帮你生成一个文件名。
- 快速做键值对的存储。
我们使用UserDefaults注册一个账号密码试一下:
// 获取偏好设置对象NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];//存储数据[defaults setObject:@"zxb10" forKey:@"name"];[defaults setObject:@"zxbnb666" forKey:@"password"];// 同步调用,立刻写到文件中,不写这个方法会异步,有延迟[defaults synchronize];// 需要验证账号密码的地方,获取偏好设置对象NSUserDefaults *defaultsA = [NSUserDefaults standardUserDefaults];NSString *name = [defaultsA objectForKey:@"name"];NSString *password = [defaultsA objectForKey:@"password"];NSLog(@"name:%@ password:%@", name, password);

数据库存储
SQLite:
是目前主流的嵌入式关系型数据库,其最主要的特点就是轻量级、跨平台,当前很多嵌入式操作系统都将其作为数据库首选。CoreData:
CoreData是iOS5之后才出现的一个框架,本质上是对SQLite的一个封装,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象,在这个过程中不需要手动编写任何SQL语句,CoreData封装了数据库的操作过程,以及数据库中数据和OC对象的转换过程。通过CoreData管理应用程序的数据模型,可以极大程度减少需要编写的代码数量。FMDB:
是一个处理数据存储的第三方框架,框架是对sqlite的封装,整个框架非常轻量级但又不失灵活性,而且更加面向对象。
SQLite和CoreData的区别:
CoreData可以在一个对象更新时,其关联的对象也会随着更新,相当于你更新一张表时,其关联的其他表的也会随着更新。CoreData供更简单的性能管理机制,可以限制查询记录的总数,这个类会自动更新其缓存。- 多表查询方面,
CoreData没有SQL直观,没有类似外连接,左连接等操作。
什么是序列化和反序列化,用来做什么?
- 序列化:把对象转化为字节序列的过程
- 反序列化:把字节序列恢复成对象
- 作用:把对象写到文件或者数据库中,并且读取出来
写入和读取plist文件
// 其中,Show为我们plist文件的名称,后面的plist是Show的扩展名
// 写入plist
- (void)setDataFromPlist {NSString *plist = [[NSBundle mainBundle] pathForResource:@"Show" ofType:@"plist"];NSMutableDictionary *temp = [[NSMutableDictionary alloc] init];[temp setValue:@20 forKey:@"age"];[temp setValue:@"男" forKey:@"sex"];[temp writeToFile:plist atomically:YES];
}// 读取plist
- (void)getDataFromPlist {NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Show" ofType:@"plist"];NSMutableDictionary *dataDic = [[NSMutableDictionary alloc] initWithContentsOfFile:plistPath];NSLog(@"%@", dataDic);//直接打印数据
}相关文章:
【iOS】—— 持久化
文章目录 数据持久化的目的iOS中数据持久化方案数据持久化方式分类内存缓存磁盘缓存 沙盒机制获取应用程序的沙盒路径沙盒目录的获取方式 持久化数据存储方式XML属性列表Preferences偏好设置(UserDefaults)数据库存储什么是序列化和反序列化,…...
教程 - 在 Vue3+Ts 中引入 CesiumJS 的最佳实践@2023
1. 本篇适用范围与目的 1.1. 适用范围 严格使用 Vue3 TypeScript 的前端项目,包管理器默认使用 pnpm 构建工具使用 Vite4 使用原生 CesiumJS 依赖做应用开发 客户端渲染,因为我不太熟悉 Vue 的服务端渲染,有本篇的介绍后,熟悉…...
最优化方法
一. 图论 1.最小生成树 图的生成树是它的一颗含有其所有顶点的无环连通子图,一 幅加权图的最小生成树(MST)是它的一颗权值(树中的所有边的权值之和) 最小的生成树 • 适用场景:道路规划、通讯网络规划、管道铺设、电线布设等 题目数据 kruskal算法 稀疏图&#x…...
Mongodb 多文档聚合操作处理方法二(Map-reduce 函数)
聚合 聚合操作处理多个文档并返回计算结果。您可以使用聚合操作来: 将多个文档中的值分组在一起。 对分组数据执行操作以返回单个结果。 分析数据随时间的变化。 要执行聚合操作,您可以使用: 聚合管道 单一目的聚合方法 Map-reduce 函…...
ant design vue j-modal 修改高度
问题描述 今天在项目中遇到关于j-modal组件修改弹窗大小问题,我尝试使用直接使用:height"300",没用效果,弹窗大小依然和没改之前一样,后来找到了这种方式可以去修改j-modal弹窗大小,下面来看下代码实现&…...
spring学习笔记七
一、自动装配 1.1、BookDao接口和实现类 public interface BookDao {void save(); } public class BookDaoImpl implements BookDao {public void save(){System.out.println("book dao save......");} } 1.2、BookService接口和实现类 public interface BookSer…...
hw技战法整理参考
目录 IP溯源反制 账户安全策略及预警 蜜罐部署联动方案...
uniapp 全局数据(globalData)的设置,获取,更改
globalData,这是一种简单的全局变量机制。这套机制在uni-app里也可以使用,并且全端通用 因为uniapp基本上都是将页面,或者页面中相同的部分,进行组件化,所以会存在父,子,(子…...
Profinet转EtherNet/IP网关连接AB PLC的应用案例
西门子S7-1500 PLC(profinet)与AB PLC以太网通讯(EtherNet/IP)。本文主要介绍捷米特JM-EIP-PN的Profinet转EtherNet/IP网关,连接西门子S7-1500 PLC与AB PLC 通讯的配置过程,供大家参考。 1, 新建工程&…...
Python组合模式介绍、使用方法
一、Python组合模式介绍 概念: 组合模式(Composite Pattern)是一种结构型设计模式,它通过将对象组合成树状结构来表示“整体/部分”层次结构,让客户端可以以相同的方式处理单个对象和组合对象。 功能: 统一对待组合对象和叶子对…...
生成模型和判别模型工作原理介绍
您解决的大多数机器学习和深度学习问题都是从生成模型和判别模型中概念化的。在机器学习中,人们可以清楚地区分两种建模类型: 将图像分类为狗或猫属于判别性建模生成逼真的狗或猫图像是一个生成建模问题神经网络被采用得越多,生成域和判别域就增长得越多。要理解基于这些模型…...
shardingsphere读写分离配置
注: 如果是升级之前的单库单表,要将之前的 数据库接池 druid-spring-boot-starter 注释掉,换成 druid,否则无法连接数据库。 原因: 因为数据连接池的starter(比如druid)可能会先加载并且其创…...
登录报错 “msg“:“Request method ‘GET‘ not supported“,“code“:500
1. 登录失败 2. 排查原因, 把 PostMapping请求注释掉, 或改成GetMapping请求就不会报错 3. 找到SecurityConfig.java , 新增 .antMatchers("/**/**").permitAll() //匹配允许所有路径 4. 登录成功...
Python 日期和时间
Python 日期和时间 Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能。 Python 提供了一个 time 和 calendar 模块可以用于格式化日期和时间。 时间间隔是以秒为单位的浮点小数。 每个时间戳都以自从1970年1月1日午夜(历元&…...
pytorch的发展历史,与其他框架的联系
我一直是这样以为的:pytorch的底层实现是c(这一点没有问题,见下边的pytorch结构图),然后这个部分顺理成章的被命名为torch,并提供c接口,我们在python中常用的是带有python接口的,所以被称为pytorch。昨天无意中看到Torch是由lua语言写的&…...
Kibana-elastic--Elastic Stack--ELK Stack
Kibana 是什么? | Elastic 将数据转变为结果、响应和解决方案 使用 Kibana 针对大规模数据快速运行数据分析,以实现可观测性、安全和搜索。对来自任何来源的任何数据进行全面透彻的分析,从威胁情报到搜索分析,从日志到应用程序监测…...
Docker复杂命令便捷操作
启动所有状态为Created的容器 要启动所有状态为"created"的Docker容器,可以使用以下命令: docker container start $(docker container ls -aq --filter "statuscreated")上述命令执行了以下步骤: docker container l…...
Python中的datetime模块
time模块用于取得UNIX纪元时间戳,并加以处理。但是,如果以方便的格式显示日期,或对日期进行算数运算,就应该使用datetime模块。 目录 1. datetime数据类型 1) datetime.datetime.now()表示特定时刻 2)da…...
Flutter - 微信朋友圈、十字滑动效果(微博/抖音个人中心效果)
demo 地址: https://github.com/iotjin/jh_flutter_demo 代码不定时更新,请前往github查看最新代码 前言 一般APP都有类似微博/抖音个人中心的效果,支持上下拉刷新,并且顶部有个图片可以下拉放大,图片底部是几个tab,可…...
MySQL检索数据和排序数据
目录 一、select语句 1.检索单个列(SELECT 列名 FROM 表名;) 2.检索多个列(SELECT 列名1,列名2,列名3 FROM 表名;) 3.检索所有的列(SELECT * FROM 表名;) 4.检索不同的行&#x…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案
目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后,迭代器会失效,因为顺序迭代器在内存中是连续存储的,元素删除后,后续元素会前移。 但一些场景中,我们又需要在执行删除操作…...
