【iOS】—— 持久化

news2024/11/27 10:41:50

文章目录

  • 数据持久化的目的
  • 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个文件夹:DocumentsLibrarySystemDatatmp,当前应用程序只能访问该目录下的文件。

沙盒目录的获取方式

//获取沙盒根路径
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

如果对象是NSStringNSDictionaryNSArrayNSDataNSNumber等类型,就可以使用
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的封装,整个框架非常轻量级但又不失灵活性,而且更加面向对象。

SQLiteCoreData的区别:

  • 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);//直接打印数据
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/793822.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

构建外卖系统小程序,订单管理功能实现步骤详解

外卖系统小程序是近年来越来越受欢迎的一种订餐方式,方便快捷,并且可以减少人与人之间的接触,更加卫生安全。为了搭建一个完善的外卖系统小程序,订单管理功能是必不可少的一部分。在本文中,我们将详细介绍如何实现订单…

java 支持jsonschema

入参校验产品化 schema_xsd可视化编辑器_个人渣记录仅为自己搜索用的博客-CSDN博客 jsonchema的生成 支持v4的jackson-jsonSchema GitHub - mbknor/mbknor-jackson-jsonSchema: Generate JSON Schema with Polymorphism using Jackson annotations jackson-module-jsonSchema …

三、函数-4.日期函数

一、常见函数 二、示例 -- 返回当前日期current date 2023-07-26 select curdate();-- 返回当前时间current time 15:21:14 select curtime();-- 返回当前日期和时间 2023-07-26 15:21:33 select now();-- 获取指定data的年份 2023 select year(now());-- 获取指…

C++教程 从0开始

0基础C教程 从0开始 课堂现在开始 如需学习 请订阅该标签 什么是C? 这个不是太重要 自行查看该链接即可 C_百度百科C(c plus plus)是一种计算机高级程序设计语言,由C语言扩展升级而产生,最早于1979年由本贾尼斯特劳…

SpringBoot2为什么默认使用CGLib不再使用JDK动态代理

SpringBoot2为什么默认使用CGLib不再使用JDK动态代理 CGLib和JDK动态代理对比1. 不需要实现接口2. 性能3. 代理对象的创建4. 调用方法 2. CGLib使用 CGLib和JDK动态代理对比 1. 不需要实现接口 JDK动态代理类要求目标类必须实现接口,而CGLib动态代理可以直接代理普通类(非接口…

【大数据运维-ambari】自定义fair-scheduler.xml配置文件导致ambari-server启动失败

将自定义fair-scheduler.xml放到 /var/lib/ambari-server/resources/stacks/HDP/3.0/services/YARN/configuration目录下,重启ambari-server失败: 日志显示: 进ambari数据库查看发现数据应该是对的。 删掉之前自定义的文件fair-scheduler.x…

Visual Studio2022报错 无法打开 源 文件 “openssl/conf.h“解决方式

目录 问题起因问题解决临时解决方案 问题起因 近一段时间有了解到Boost 1.82.0新添加了MySQL库,最近一直蠢蠢欲动想要试一下这个库 所以就下载了源码并进行了编译(过程比较简单,有文档的) 然后在VS2022中引入了Boost环境&#xf…

628. 三个数的最大乘积

628. 三个数的最大乘积 class Solution {public int maximumProduct(int[] nums) {Arrays.sort(nums); return Math.max(nums[nums.length-1]*nums[nums.length-2]*nums[nums.length-3],nums[0]*nums[1]*nums[nums.length-1]);} }

Tribon二次开发-Excel/VBA数据抽取

在Tribon的启动目录下有两个样板Excel,通过在Excel里面抽取数据。 源文件存储在C:\Tribon\M3\customise 打开OutfiList,出现一系列按钮,都是抽取数据的功能按钮,可以点击按钮看看界面, 按照界面提示输入相关参数&…

LeetCode·每日一题·771. 宝石与石头·哈希

作者:小迅 链接:https://leetcode.cn/problems/jewels-and-stones/solutions/2356302/ha-xi-zhu-shi-chao-ji-xiang-xi-by-xun-ge-jnmr/ 来源:力扣(LeetCode) 著作权归作者所有。商业转载请联系作者获得授权&#xff0…

超长三伏天,“高温”模式下如何清凉一“夏”

俗话说“冷在三九,热在三伏”,三伏天一登场便霸占话题热搜C位,异常闷热的天气不仅容易给生活带来不便,还会对健康造成影响,所以大家要注意科学防暑,掌握正确的避暑指南。 今年三伏天超长待机40天&#x…

小白带你学习linux数据库—用户权限管理(二十九)

前言 数据库用户权限管理是指在数据库管理系统中,对数据库用户进行权限控制和管理的过程。它确定了每个用户可以执行的操作和访问的资源范围。 一、概述 数据库用户权限管理是数据库系统中非常重要的一个方面,它用于控制不同用户访问和操作数据库的权…

官方劝退?!大学专业批量撤销!计算机专业还“安全”吗?

大学生人人都有本难念的经。现如今比“毕业即失业”的应届生更惨的,大概就是专业被撤销的大学生了。 一觉醒来,人没毕业,专业就没了,一不小心成了学校里“XX专业”的关门弟子,“还没毕业就被社会淘汰了”。 即便是比较…

基于深度学习的高精度狗狗检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要:基于深度学习的高精度狗狗检测识别系统可用于日常生活中检测与定位120类狗狗目标,利用深度学习算法可实现图片、视频、摄像头等方式的狗狗目标检测识别,另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5目标检测模型训练…

软件检测报告编写注意事项有哪些?权威的软件测评中心安利

软件检测报告是一项对软件进行全面测试和评估的结果总结,通过对软件的功能、性能、安全性等方面的测试,以及通过分析软件的可靠性和稳定性,来评估软件的质量和合规性。那么软件检测报告的编写有哪些注意事项呢? 1、软件检测报告有哪些常见的…

前端开发实习总结参考范文

▼前端开发实习总结篇四 读了三年的大学,然而大多数人对本专业的认识还是不那么透彻,学的东西真正能够学以致用的东西很少,大家都抱怨没有实践的机会,在很多同学心里面对于本专业还是很茫然。直到即将毕业的时候才知道我们以前学…

day40-3d Background Boxes(3D背景盒子转换)

50 天学习 50 个项目 - HTMLCSS and JavaScript day40-3d Background Boxes&#xff08;3D背景盒子转换&#xff09; 效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewp…

【Java基础学习打卡17】基本数据类型

目录 前言一、数据类型分类1.基本数据类型2.引用数据类型 二、基本数据类型1.整数类型2.浮点类型3.字符类型4.布尔类型 三、基本数据类型转换1.自动类型转换2.强制类型转换 总结 前言 本文介绍Java中的基本数据类型&#xff0c;共有8种&#xff0c;是Java编程的基础。编程的实…

7-Linux下的网络配置

win下的ipconfig linux下的ifconfig ping 测试主机之间的连通性 设置主机名和hosts映射 设置主机名 查看主机名&#xff1a;hostname修改主机名&#xff1a;vim /etc/hostname &#xff0c;重启后生效 ![[1-Linux目录结构#^f9a9d2]] 设置hosts映射 在win中&#xff1a; …

flask实现一个登录界面

flask实现一个登录界面 基础的Flask项目结构 forms.py&#xff1a;定义登录表单和表单字段的文件。templates/login.html&#xff1a;用于渲染登录表单的 HTML 模板文件。routes.py&#xff1a;定义应用的路由和视图函数的文件。__init__.py&#xff1a;创建并初始化 Flask 应…