iOS——持久化

news2024/12/26 11:46:52

iOS的数据存储机制

沙盒机制

应用沙盒文件夹包含了:

  • Application(应用程序包):包含了所有的资源文件和和可执行文件,上架前经过数字签名,上架后不可修改。

  • Documents:文档目录,要保存程序生成的数据,会自动被分到iCloud中。保存应用运行时生成的需要持久化的数据,iTunes同步设备时会备份该目录。例如,游戏应用可将游戏存档保存在该目录。(注意点:不要保存从网络上下载的文件,否则会无法上架!)

  • Library:用户偏好,使用 NSUserDefault 直接读写!如果要想数据及时写入磁盘,还需要调用一个同步方法。该目录下有两个子目录:

  1. Caches:存放体积大又不需要备份的数据
  2. Preference:保存应用的所有偏好设置,iCloud会备份设置信息
  • Tmp:临时文件,系统会自动清理。重新启动就会清理。保存应用运行时所需的临时数据,使用完毕后再将相应的文件从该目录删除。应用没有运行时,系统也可能会清除该目录下的文件。iTunes同步设备时不会备份该目录。重新启动手机,tmp 目录会被清空。系统磁盘空间不足时,系统也会自动清理

获取沙盒目录

  • 沙盒根目录:
NSString *home = NSHomeDirectory();
  • 利用 NSSearchPathForDirectoriesInDomains 函数获取Documents目录:
// NSUserDomainMask 代表从用户文件夹下找
// YES 代表展开路径中的波浪字符“~”
NSArray *array =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO);
// 在iOS中,只有一个目录跟传入的参数匹配,所以这个集合里面只有一个元素
NSString *documents = [array objectAtIndex:0];
  • 获取tmp目录:
NSString *tmp = NSTemporaryDirectory();
  • Library/Caches:利用 NSSearchPathForDirectoriesInDomains 函数 (将函数的第2个参数改为:NSCachesDirectory即可)
  • Library/Preference:通过NSUserDefaults类存取该目录下的设置信息。

iOS的数据持久化方式

内存缓存和磁盘缓存

缓存分为内存缓存和磁盘缓存两种。
其中内存是指当前程序的运行空间,缓存速度快容量小,是临时存储文件用的,供CPU直接读取,比如说打开一个程序,他是在内存中存储,关闭程序后内存就又回到原来的空闲空间;
磁盘是程序的存储空间,缓存容量大、速度慢、可持久化。与内存不同的是磁盘是永久存储东西的,只要里面存放东西,不管运行不运行 ,他都占用空间!磁盘缓存是存在Library/Caches。

NSCache

plist(属性列表)

Plist(NSArray\NSDictionary),只存储数组、字典,但是数组和字典里不能有自定义对象。
属性列表是一种XML格式的文件,拓展名为plist如果对是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,就可以使用writeToFile:atomically:方法直接将对象写到属性列表文件中。

将NSArray、NSDictionary等归档到plist文件中,可以有效地实现数据持久化,方便在应用的不同会话中保存和加载数据。
可以将用户的偏好设置、应用配置项等保存到plist文件中,用户在重新启动应用时能够恢复之前的设置。
将应用所需的静态数据(例如,菜单项、静态内容、预定义选项等)保存到plist文件中,方便在应用中读取和使用。
对于不需要数据库管理的小规模数据,可以通过plist文件来实现简单的数据持久化,避免使用更加复杂的数据库系统。

将一个NSDictionary对象归档到一个plist属性列表中:

// 将数据封装成字典
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:@"张三" forKey:@"name"];
[dict setObject:@"155xxxxxxx" forKey:@"phone"];
[dict setObject:@"27" forKey:@"age"];
// 将字典持久化到Documents/stu.plist文件中
NSArray *array =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO);
        NSString *documentsDirectory = [array firstObject];
        NSString *path = [documentsDirectory stringByAppendingPathComponent:@"stu.plist"];
[dict writeToFile:path atomically:YES];

恢复NSDictionary读取属性列表,恢复NSDictionary对象:

NSArray *array =  NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO);
        NSString *documentsDirectory = [array firstObject];
        NSString *path = [documentsDirectory stringByAppendingPathComponent:@"stu.plist"];
// 读取Documents/stu.plist的内容,实例化
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
NSLog(@"name:%@", [dict objectForKey:@"name"]);
NSLog(@"phone:%@", [dict objectForKey:@"phone"]);
NSLog(@"age:%@", [dict objectForKey:@"age"]);

偏好设置Preferences

偏好设置指的是使用NSUserDefaults类来存储和检索应用程序的设置和偏好数据。NSUserDefaults提供了一种简单的方法来存储和读取用户的偏好数据,例如应用的设置、用户选项等。它适用于存储简单的数据,如字符串、数字、布尔值、日期和数据对象。
如,保存用户名、字体大小、是否自动登录:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:@"张三" forKey:@"username"];
[defaults setFloat:18.0f forKey:@"text_size"];
[defaults setBool:YES forKey:@"auto_login"];

读取上次保存的设置

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *username = [defaults stringForKey:@"username"];
float textSize = [defaults floatForKey:@"text_size"];
BOOL autoLogin = [defaults boolForKey:@"auto_login"];

UserDefaults设置数据时,不是立即写入,而是根据时间戳定时地把缓存中的数据写入本地磁盘。所以调用了set方法之后数据有可能还没有写入磁盘应用程序就终止了。出现以上问题,可以通过调用synchornize方法[defaults synchornize];强制写入。

归档和解档

如果仅仅存储简单的数据类型(如字符串、数字),可以直接写入文件。但是当需要存储复杂的对象(如自定义类、嵌套的数组和字典)时,归档和解档可以将这些复杂对象转换为可存储的格式,并在需要时恢复原始对象。

  • 简化数据存储和读取:
    归档和解档过程自动处理对象的属性和关系,简化了数据存储和读取的代码。开发者无需手动处理对象的每个属性,也无需手动解析存储的数据。

  • 确保数据完整性和一致性:
    通过归档和解档,可以确保对象的所有属性都被正确存储和恢复,避免手动存储和读取过程中可能出现的遗漏和错误。

  • 支持持久化和传输:
    序列化的数据可以方便地写入文件、数据库或通过网络传输。这样,应用程序可以在不同设备或会话之间共享数据。

  • 安全性:
    使用安全编码选项,归档和解档可以防止反序列化过程中出现的数据篡改和不安全数据的注入。

NSKeyedArchiver

NSKeyedArchiver如果对象是NSString、NSDictionary、NSArray、NSData、NSNumber等类型,可以直接用NSKeyedArchiver进行归档和恢复。
不是所有的对象都可以直接用这种方法进行归档,只有遵守了NSCoding协议的对象才可以。
NSCoding 协议有2个方法:

  • encodeWithCoder: 每次归档对象时,都会调用这个方法。一般在这个方法里面指定如何归档对象中的每个实例变量,可以使用encodeObject:forKey:方法归档实例变量。
  • initWithCoder: 每次从文件中恢复(解码)对象时,都会调用这个方法。一般在这个方法里面指定如何解码文件中的数据为对象的实例变量,可以使用decodeObject:forKey方法解码实例变量。

NSData

将多个对象写入到同一个文件中,那么就要使用NSData来进行归档对象。 NSData可以为一些数据提供临时存储空间,以便随后写入文件,或者存放从磁盘读取的文件内容。可以使用[NSMutableData data]创建可变数据空间。

请添加图片描述

归档(编码)

// 新建一块可变数据区
NSMutableData *data = [NSMutableData data];
// 将数据区连接到一个NSKeyedArchiver对象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
// 开始存档对象,存档的数据都会存储到NSMutableData中
[archiver encodeObject:person1 forKey:@"person1"];
[archiver encodeObject:person2 forKey:@"person2"];
// 存档完毕(一定要调用这个方法)
[archiver finishEncoding];
// 将存档的数据写入文件
[data writeToFile:path atomically:YES];

NSData-从同一文件中恢复2个Person对象恢复(解码):

// 从文件中读取数据
NSData *data = [NSData dataWithContentsOfFile:path];
// 根据数据,解析成一个NSKeyedUnarchiver对象
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
Person *person1 = [unarchiver decodeObjectForKey:@"person1"];
Person *person2 = [unarchiver decodeObjectForKey:@"person2"];
// 恢复完毕
[unarchiver finishDecoding];

利用归档实现深复制:

// 临时存储person1的数据
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:person1];
// 解析data,生成一个新的Person对象
Student *person2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
// 分别打印内存地址
NSLog(@"person1:0x%x", person1);  // person1:0x7177a60
NSLog(@"person2:0x%x", person2); // person2:0x7177cf0

SQL本地数据库

CoreData

CoreData 是基于 sqlite 的封装。

FMDB

FMDB是iOS平台的SQLite数据库框架。
FMDB以OC的方式封装了SQLite的C语言API

使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码。
对比苹果自带的Core Data框架,更加轻量级和灵活。
提供了多线程安全的数据库操作方法,有效地防止数据混乱。

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

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

相关文章

华为OD机试 - 最大相连男生数 - 矩阵(Python/JS/C/C++ 2024 E卷 200分)

华为OD机试 2024E卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试真题(Python/JS/C/C)》。 刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,…

[数据集][目标检测]水面垃圾检测数据集VOC+YOLO格式2027张1类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2027 标注数量(xml文件个数):2027 标注数量(txt文件个数):2027 标注…

信创实践(3):基于x2openEuler将CentOS升级成openEuler,享受其带来的创新和安全特性

引言: 在当前的 IT 行业中,创新和安全性是两大关键趋势。随着 CentOS 停止维护,许多用户正在寻找替代方案,以保持其系统的更新和安全。openEuler 作为一个强大的开源操作系统,成为了理想的迁移目标。本教程将指导您如…

大语言模型的上下文窗口(Context Windows):对人工智能应用的影响

大语言模型(LLMs)极大地提升了人工智能在理解和生成类人文本方面的能力。其中一个影响其效用的基本方面是它们的 “上下文窗口”—— 这个概念直接影响着这些模型接收和生成语言的有效性。我将深入探讨上下文窗口是什么、它们对人工智能应用的影响以及组…

【通俗理解】Baseline在竞赛中的意义——性能比较的标准尺

【通俗理解】Baseline在竞赛中的意义——性能比较的标准尺 关键词提炼 #Baseline #竞赛标准 #算法性能 #性能比较 #改进评估 #魔改基础 #优势彰显 第一节:Baseline的类比与核心概念【尽可能通俗】 1.1 Baseline的类比 Baseline在竞赛中就像是一场跑步比赛的起跑…

【IEEE独立出版 | 最终截稿时间:2024年9月9日23:59】第三届人工智能、物联网和云计算技术国际会议(AIoTC 2024)

【IEEE独立出版 | 最终截稿时间:2024年9月9日23:59】 第三届人工智能、物联网和云计算技术国际会议(AIoTC 2024) 2024 3rd International Conference on Artificial Intelligence, Internet of Things and Cloud Computing Technology 202…

轻松驾驭开学季,智慧校园综合解决方案!

智慧校园是指运用先进的信息技术手段和智能化系统,对学校内部各种教育资源、管理流程和服务进行数字化、网络化、智能化的整合与优化,提供高效便捷的教育教学和管理服务环境的校园。 智慧校园建设从哪些方面入手呢? 1.智慧食堂管理系统 基于…

[3.4]【机器人运动学MATLAB实战分析】平面RRR机器人正运动学MATLAB计算

本文重点介绍平面RRR机械手结构的正运动学方程的算例,这些是工业机器人中经常遇到的。平面RRR机器人运动学建模如下: 机器人模型: 表1三连杆平面臂的DH参数 由于所有关节都是转动型的,对每一个关节都具有相同的定义的齐次变换矩阵结构,即: 则计算正运动学方程得:

xAI巨无霸超级计算机上线:10万张H100 GPU,计划翻倍至20万张

在短短四个多月的时间里,埃隆马斯克的X公司(前身为Twitter)推出了世界上最强劲的人工智能训练系统。名为Colossus的超级计算机使用了多达10万张NVIDIA H100 GPU进行训练,并计划在未来几个月内再增加5万张H100和H200 GPU。 “本周末…

时间序列神器Prophet教程-入门教程

公众号:尤而小屋编辑:Peter作者:Peter 大家好,我是Peter~ 今天给大家分享一个时间序列预测神器Prophet的简易入门教程。 什么是Prophet Prophet是一种基于加法模型的时间序列预测工具,由Facebook的数据科学团队开发…

实战训练与源码教程:用Real-ESRGAN对抗生成超分技术实现超高清图像!

目录 前言 超分数据如何构造呢? Real-ESRGAN 1. 高质量细节重建 2. 真实感和自然度 3. 处理真实世界数据 4. 多尺度和多种类型的输入 5. 视觉效果的提升 超分如何退化 1. 模糊处理 2. 噪声处理 3. 压缩失真 4. 训练数据的退化模拟 2.经典退化模型◆退…

【苍穹外卖】Day 7 缓存、购物车相关接口

1 缓存 存在问题: 用户端小程序展示的菜品数据都是通过査询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 >解决: 通过 Redis 来缓存菜品数据,减少数据库查询操作 缓存逻辑分析: 每个分…

PyDracula:用 PySide6 和 PyQt6打造现代感 Python GUI 的利器

PyDracula 是一个基于 PySide6 或 PyQt6 的 Python GUI 库,它以其现代、美观、易于定制的特点而闻名。PyDracula 融合了流行的 Dracula 主题,并提供了丰富的功能,让开发者可以轻松构建出具有吸引力的图形界面。本文将详细介绍 PyDracula 的核…

【Godot4.3】CanvasShape资源化改造

概述 通过把之前自定义的CanvasShape类变成资源类型,将可以同时用于CanvasItem绘图和创建扩展的Node2D和Polygon2D节点等。 本篇就完成CanvasShape类的资源化改造,并记录改造过程和思路。 CanvasShape资源类型体系 CanvasShape仍然为图形基类&#xf…

Android Auto未来可能支持无线电广播

通过Android Auto,可以在车载收音机上使用 Google 地图、音乐、收听播客,还能获取天气等基本信息。最近,国外科技媒体9to5Google通过分析 Android Auto v12.3 和 v12.4的应用程序的代码发现了一些提示信息,特别提到了 AM、FM、HD …

【Protobuf】xml、json与protobuf有什么区别,protobuf详解(保姆篇)

文章目录 简介Protobuf 的原理安装 Protobuf 编译器在 Python 中使用 Protobuf安装语言特定的 Protobuf 库定义消息结构生成代码使用 Protobuf 进行序列化和反序列化 在 Java 中使用 Protobuf安装和配置编译 .proto 文件使用生成的 Java 类创建和序列化对象 代码注释 高级特性嵌…

LabVIEW灵活集成与调试的方法

在LabVIEW开发中,为了构建一个既便于调试又能灵活集成到主VI中的控制VI,开发者需要采用适当的编程方式和架构。常见的选择包括模块化设计、状态机架构以及事件驱动编程。这些方法有助于简化调试过程、提高系统的稳定性,并确保代码的重用性和可…

day43-测试平台搭建之前端vue学习-基础2

目录 一、数据代理 二、事件处理 三、计算属性 四、监控属性 五、绑定样式 六、今日学习思维导图 一、数据代理 1.1.数据代理:通过一个对象代理对另外一个对象中属性的操作 (读/写) 1.2.Vue中数据代理的好处:更加方便的操作data中的数据 1.3.基本原…

vue2结合element-ui使用tsx格式实现formily自定义组件

简洁 在公司实习,需要参与开发一个基于formily的低代码平台,实现自定义formily组件,在此记录一下。 示例源码 demo源码 实现思路 开始实现自定义组件之前最好先看一下formily官网的core、vue、element部分,如果有能力也可以阅…

2024数学建模国赛A题word版成品论文30页【附带完整解题代码+可视化图表】

0906 0:30 v1.0 问题一、问题二的完整可运行代码,模型建立与求解这一部分的论文。 0906 5:20 v1.1 增加了第三问的完整可运行代码和第二、三问的“模型建立与求解”的论文。(即1-3问的代码、模型建立与求解、算法设计、结果分析) 1-4问完整可…