【iOS】数据持久化(一)之Plist文件、Preference(NSUserDefaults类)

目录

    • 什么是Plist文件?
      • plist可以存储哪些数据类型
      • plist文件数据的读取与存储
    • Perference(NSUserDefaults)
      • 使用方法
      • registerDefaults: 方法的使用


什么是Plist文件?

Plist文件(属性列表)是将某些特定的类,通过XML文件的方式保存在目录中。

什么是 XML?
可扩展标记语言 (XML) 允许您以可共享的方式定义和存储数据。XML 支持计算机系统(如网站、数据库和第三方应用程序)之间的信息交换。预定义的规则简化了在任何网络上以 XML 文件的形式传输数据的过程,接收者可以使用这些规则准确高效地读取数据。

我们以 Xcode自动生成的plist文件为例,观察其结构,当我们新建一个项目时后,会发现有一个Info.plist文件,里面有很多参数和配置:
请添加图片描述
这是Xcode为我们自动生成的plist文件,用来保存当前项目的一些配置,Xcode为ta集成了很多预置的KeyValue

右键Info.plist文件->Open As->Source Code,用文本编辑器打开plist文件:
请添加图片描述
可以看到plist文件就是一个XML文件,key为键,string为对应的值

plist可以存储哪些数据类型

可以发现每一个键值对中间都有一个Type,不难理解这就是value的类型,右键查看:
请添加图片描述
plist文件可以被序列化的类型(可以被存储的类型)只有这几种:基本数据类型(NSStringNSNumberNSDateBOOL),对象数据类型(NSData/NSMutableData),集合类型(NSArray/NSMutableArrayNSDictionary/NSMutableDictionary),不能保存自定义对象

不难理解,这些数据可以被转换保存到一个纯文本文件(区别于二进制文件)中

plist文件数据的读取与存储

1. 读取
一般情况下,plist文件存储在沙盒的 /Documents中,所以要获取某个plist文件,只需要知道其文件名即可。用过以下方法获取plist数据(一般以NSArray或NSDictionary的形式保存):

//获取文件路径
NSString* path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
NSString* fileName = [path stringByAppendingPathComponent: @"filename.plist"];//提取plist数据
NSArray* result = [NSArray arrayWithContentsOfFile: fileName];
NSLog(@"%@", result);

2. 存储

往plist文件写入数据直接用相应类型的writeToFile:方法即可

NSArray* array = @[@"ott", @"123", @"abc"];
[array writeToFile: fileName atomically: YES];

writeToFile: atomically:方法中atomically表示是否需要先写入一个辅助文件,再把辅助文件拷贝到目标文件地址,更安全的写入文件,一般该值为YES

运行后,Documents目录:
在这里插入图片描述
array以XML格式保存在本地

这个方法也可用于其他数据文件(.plist.txt.data等格式的文件),在沙盒中指定某一路径,新建并将数据文件保存在这一路径(同样,自定义对象是不能直接存入的,但是可以通过归档存为.data文件)

Perference(NSUserDefaults)

Perference(偏好设置)顾名思义就是专门用来存储系统的偏好配置、用户设置的参数和App的状态等少量信息的,一般不保存其他数据

使用NSUserDefaults类,以字典形式保存数据,iOS会自动把字典中的键值对转换成对应的XML文件(也就是plist文件),该文件存放在沙盒的 /Library/Preferences/ 目录下

NSUserDefaults是单例类,此类实际上就是对plist文件操作进行了封装,更方便我们直接操作

使用方法

  1. 获取NSUserDefaults文件
NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
  1. 向plist文件写入内容
[userDefaults setObject: @"3G!!!" forKey: @"obj"];
[userDefaults setBool: YES forKey: @"isMale"];
[userDefaults setInteger: 20 forKey: @"age"];
  1. 立即同步
[userDefaults synchronize];

如果没有调用synchronize方法,系统会根据I/O情况(读取、写入和更新)不定时刻地将数据保存到文件中(以周期性间隔自动调用的同步方法使内存中的缓存与用户的默认数据库保持同步,而不是及时写入的),所以为防止在写完NSUserDefaults后程序退出导致数据丢失,需要立即写入文件的话就必须调用synchronize方法

  1. 读取文件中的内容
NSString* userName = [userDefaults objectForKey: @"obj"];
BOOL genderIsMale = [userDefaults boolForKey: @"isMale"];
NSInteger age = [userDefaults integerForKey: @"age"];
NSLog(@"%@ %d %ld", userName, genderIsMale, age);
[userDefaults removeObjectForKey: @"isMale"];

这样就会将所有数据保存到同一个文件中(即Preference目录下的一个以此应用包名称来命名的plist文件):
在这里插入图片描述

注:

返回值从NSUserDefaults是不可改变的,即使设置一个值可变对象。 例如,如果设置一个可变的字符串值作为"MyStringDefault",则稍后使用stringForKey:检索的字符串将是不可变的

registerDefaults: 方法的使用

NSUserDefaults除了保存和读取功能外,还为我们提供了一个很便捷的方法:registerDefaults:
请添加图片描述

ta的参数是一个字典类型,作用仅仅是为了定义一组默认的数据,这些默认的数据是不会被保存到plist文件中的,我们需要手动变更这些数据然后保存

举一个例子,我们可以使用这个方法来确认App是否是第一次启动:

//注册一个默认值
[userDefaults registerDefaults: @{@"firstRun" : @YES}];//第一次启动还没有生成plist文件,就会读取上面注册的默认值
BOOL isFirstRun = [userDefaults boolForKey: @"firstRun"];//是第一次启动
if (isFirstRun) {NSLog(@"这是第一次启动");//手动改为NO,保存到plist文件中[userDefaults setBool: NO forKey: @"firstRun"];
} else {NSLog(@"不是第一次启动");
}

再次强调,registerDefaults方法中的字典数据是不会保存到plist文件中的,当我们读取某个键值时,如果没有plist文件plist文件中没有找到对应的键值,那么就会从registerDefaults方法的字典参数中寻找对应的键值,拿到默认值。

当我们做了相应处理后,再手动把这个键值内容保存到plist中,下次读取就会是直接读取plist文件中的键值,而不是读取registerDefaults中参数的字典内容了

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

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

相关文章

python运行hhblits二进制命令的包装器类

hhblits 是 HMM-HMM(Hidden Markov Model to Hidden Markov Model)比对方法的一部分,也是 HMMER 软件套件中的工具之一。与 hhsearch 类似,hhblits 也用于进行高效的蛋白质序列比对,特别擅长于检测远缘同源性。 hh-su…

筑牢思想防线——建行驻江门市分行纪检组举办2023年清廉合规大讲堂

为推动廉洁教育打通“最后一公里”,近日,建行驻江门市分行纪检组举办江门市分行2023年清廉合规大讲堂。 本次大讲堂检察官结合一线办案经历,从防范化解金融风险、预防金融从业人员犯罪等方面对全辖员工进行了深入浅出地的讲解,引导…

代码随想录算法训练营第五十二天|1143.最长公共子序列 1035.不相交的线 53. 最大子序和

文档讲解:代码随想录 视频讲解:代码随想录B站账号 状态:看了视频题解和文章解析后做出来了 1143.最长公共子序列 class Solution:def longestCommonSubsequence(self, text1: str, text2: str) -> int:dp [[0] * (len(text2) 1) for _ i…

C++——stack和queue

目录 stack的介绍和使用 stack的使用 queue的介绍和使用 queue的使用 容器适配器 deque的介绍 deque的缺陷 priority_queue的介绍和使用 priority_queue的使用 仿函数 反向迭代器 stack的介绍和使用 在原来的数据结构中已经介绍过什么是栈了,再来回顾一下…

视频监控平台EasyCVR+智能分析网关+物联网,联合打造智能环卫监控系统

一、背景介绍 城市作为人们生活的载体,有着有无数楼宇和四通八达的街道,这些建筑的整洁与卫生的背后,是无数环卫工作人员的努力。环卫工人通过清理垃圾、打扫街道、清洗公共设施等工作,保持城市的整洁和卫生,防止垃圾…

【机器学习 | 白噪声检验】检验模型学习成果 检验平稳性最佳实践,确定不来看看?

🤵‍♂️ 个人主页: AI_magician 📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。 👨‍💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!&…

C++ Day09 容器

C-STL01- 容器 引入 我们想存储多个学员的信息 , 现在学员数量不定 通过以前学习的知识 , 我们可以创建一个数组存储学员的信息 但是这个数组大小是多少呢 ? 过大会导致空间浪费 , 小了又需要扩容 对其中的数据进行操作也较为复杂 每次删除数据后还要对其进行回收等操作…

cookie的跨站策略 跨站和跨域

借鉴:Cookie Samesite简析 - 知乎 (zhihu.com) 1、跨站指 协议、域名、端口号都必须一致 2、跨站 顶级域名二级域名 相同就行。cookie遵循的是跨站策略

PowerDesigner异构数据库转换

主要流程:sql->pdm->cdm->other pdm->sql 1.根据sql生成pdm 2.根据pdm生成cdm 3.生成其他类型数据库pdm

【Java】认识String类

文章目录 一、String类的重要性二、String类中的常用方法1.字符串构造2.String对象的比较3.字符串查找4.转换5.字符串替换6.字符串拆分7.字符串截取8.其他操作方法9.字符串的不可变性10.字符串修改 三、StringBuilder和StringBuffer 一、String类的重要性 在C语言中已经涉及到…

C语言第二十五弹--打印菱形

C语言打印菱形 思路&#xff1a;想要打印一个菱形&#xff0c;可以分为上下两部分&#xff0c;通过观察可以发现上半部分星号的规律是 1 3 5 7故理解为 2对应行数 1 &#xff0c;空格是4 3 2 1故理解为 行数-对应行数-1。 上半部分代码如下 for (int i 0;i < line;i){//上…

Vivado Modelsim联合进行UVM仿真指南

打开Vivado&#xff0c;打开对应工程&#xff0c;点击左侧Flow Navigator-->PROJECT MANAGER-->Settings&#xff0c;打开设置面板。点击Project Settings-->Simulation选项卡&#xff0c;如下图所示。 将Target simulator设为Modelsim Simulator。 在下方的Compil…

OpenGL 绘制圆形平面(Qt)

文章目录 一、简介二、代码实现三、实现效果一、简介 这里使用一种简单的思路来生成一个圆形平面: 首先,我们需要生成一个单位圆,半径为1,法向量为(0, 0, 1),这一步我们可以使用一些函数生成圆形点集。之后,指定面片的索引生成一个圆形平面。当然这里为了后续管理起来方便…

Py之PyMuPDF:PyMuPDF的简介、安装、使用方法之详细攻略

Py之PyMuPDF&#xff1a;PyMuPDF的简介、安装、使用方法之详细攻略 目录 PyMuPDF的简介 PyMuPDF的安装 PyMuPDF的使用方法 1、基础用法 PyMuPDF的简介 PyMuPDF是一个高性能的Python库&#xff0c;用于PDF(和其他)文档的数据提取&#xff0c;分析&#xff0c;转换和操作。 …

Matrix

Matrix 如下是四种变换对应的控制参数&#xff1a; Rect 常用的一个“绘画相关的工具类”&#xff0c;常用来描述长方形/正方形&#xff0c;他只有4个属性&#xff1a; public int left; public int top; public int right; public int bottom; 这4个属性描述着这一个“方块…

基于JavaWeb+SSM+Vue校园水电费管理小程序系统的设计和实现

基于JavaWebSSMVue校园水电费管理小程序系统的设计和实现 源码获取入口Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 源码获取入口 Lun文目录 摘 要 III Abstract 1 1 系统概述 2 1.1 概述 2 1.2课题意义 3 1.3 主要内容 3…

使用【画图】软件修改图片像素、比例和大小

打开电脑画图软件&#xff0c;点击开始 windows附件 画图 在画图软件里选择需要调整的照片&#xff0c;点击文件 打开 在弹出窗口中选择照片后点击打开 照片在画图软件中打开后&#xff0c;对照片进行调整。按图中顺序进行 确定后照片会根据设定的值自动调整 保存…

Codeforces Round 745 (Div. 2)(C:前缀和+滑动窗口,E:位运算加分块)

Dashboard - Codeforces Round 745 (Div. 2) - Codeforces A&#xff1a; 答案就是2n!/2, 对于当前满足有k个合法下标的排列&#xff0c;就是一个n-k个不合法的下标的排列&#xff0c; 所以每一个合法排列都相反的存在一个 对称性 #include<bits/stdc.h> using nam…

【Redisson】基于自定义注解的Redisson分布式锁实现

前言 在项目中&#xff0c;经常需要使用Redisson分布式锁来保证并发操作的安全性。在未引入基于注解的分布式锁之前&#xff0c;我们需要手动编写获取锁、判断锁、释放锁的逻辑&#xff0c;导致代码重复且冗长。为了简化这一过程&#xff0c;我们引入了基于注解的分布式锁&…

JS获取时间戳的五种方法

一、JavasCRIPT时间转时间戳 JavaScript获得时间戳的方法有五种&#xff0c;后四种都是通过实例化时间对象new Date() 来进一步获取当前的时间戳&#xff0c;JavaScript处理时间主要使用时间对象Date。 方法一&#xff1a;Date.now() Date.now()可以获得当前的时间戳&#x…