【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中参数的字典内容了

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MG-HSF

作者未提供代码

“下一代云”白皮书发布:PaaS成为核心增长动力,腾讯云市场份额第二

“市场需求进一步向PaaS和SaaS层进发,使之成为公有云服务市场增长的主要动力。”11月22日,全球领先的IT研究和咨询公司国际数据公司(IDC)联合腾讯云发布“下一代云”白皮书——《聚焦平台能力,支撑智能化业务发展》指出…

python -opencv 图像锐化

python -opencv 图像锐化 图像锐化其实,是一种增强图片对比度的技术,我们可以通过计算图像的导数,把导数绝对值数值大于零的数值加回原图像,通过这种方法,可以增强图像的对比度。 实现代码如下: import c…

前缀树及其实现解析

前缀树 前缀树:又称单词查找树或键树,是一种哈希树的变种。 典型应用是用于统计和排序大量的字符串(但不仅限于字符串) 利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较。 将一组字符串数组放入…

P8599 [蓝桥杯 2013 省 B] 带分数(dfs+全排列+断点判断)

思路&#xff1a;1.深度枚举所有排列情况 2.设置为每个排列设置两个断点&#xff0c;分为三部分&#xff1a;a,b,c 3.转换为乘法判断条件&#xff0c;满足加一 代码如下&#xff1a;&#xff08;可用next_permutation全排列函数代替dfs&#xff09; #include<iostream>…

2016年全国硕士研究生入学统一考试管理类专业学位联考数学试题——解析版

文章目录 2016 级考研管理类联考数学真题一、问题求解&#xff08;本大题共 15 小题&#xff0c;每小题 3 分&#xff0c;共 45 分&#xff09;下列每题给出 5 个选项中&#xff0c;只有一个是符合要求的&#xff0c;请在答题卡上将所选择的字母涂黑。真题&#xff08;2016-01&…

Python接口自动化测试——如何搭建测试环境

前言 接口测试的方式有很多&#xff0c;比如可以用工具&#xff08;jmeter,postman&#xff09;之类&#xff0c;也可以自己写代码进行接口测试&#xff0c;工具的使用相对来说都比较简单&#xff0c;重点是要搞清楚项目接口的协议是什么&#xff0c;然后有针对性的进行选择&a…

Android——资源IDnonFinalResIds和“Attribute value must be constant”错误

一、异常描述 通过资源ID引用资源提示错误 Attribute value must be constant 二、解决方案 在根目录下的文件 gradle.properties 中添加如下配置&#xff0c;然后Sync Project android.nonFinalResIdsfalse 三、问题原因 android.nonFinalResIds 是Android开发中一个用于解…

STM32 MAP文件

文章目录 1 生成Map2 map中概念3 文件分析流程3.1 Section Cross References3.2 Removing Unused input sections from the image&#xff08;移除未使用的段&#xff09;3.3 Memory Map of the image&#xff08;映像的内存分布&#xff09;3.3.1 加载域3.3.2 运行域 4 代码运…

记录一次因内存不足而导致hiveserver2和namenode进程宕机的排查

背景 最近发现集群主节点总有进程宕机&#xff0c;定位了大半天才找到原因&#xff0c;分享一下 排查过程 查询hiveserver2和namenode日志&#xff0c;都是正常的&#xff0c;突然日志就不记录了&#xff0c;直到我重启之后又恢复工作了。 排查各种日志都是正常的&#xff0…

Doris 建表示例(七)

建表语法 使用 CREATE TABLE 命令建立一个表(Table)。更多详细参数可以查看&#xff1a; HELP CREATE TABLE; 建表语法&#xff1a; CREATE [EXTERNAL] TABLE [IF NOT EXISTS] [database.]table_name(column_definition1[, column_definition2, ...][, index_definition1[, i…

ELK架构

经典的ELK 经典的ELK主要是由Filebeat Logstash Elasticsearch Kibana组成&#xff0c;如下图&#xff1a;&#xff08;早期的ELK只有Logstash Elasticsearch Kibana&#xff09; 此架构主要适用于数据量小的开发环境&#xff0c;存在数据丢失的危险。 整合消息队列Ngin…

【Spring Cloud实战】分布式系统控制与组件应用

在现代软件开发中&#xff0c;分布式系统已经成为一种常见的架构模式&#xff0c;被广泛应用于各种规模的企业和组织中。这种架构模式通过将应用程序拆分为独立的组件&#xff0c;并分布在不同的计算机节点上运行&#xff0c;使得系统能够应对高负载和大规模的数据处理需求&…

视频剪辑达人分享:高效减片头时长并调整播放速度的技巧,提升视频品质

在视频剪辑的过程中&#xff0c;许多初学者经常会遇到一些问题&#xff0c;如片头过长、播放速度不适当等&#xff0c;这些问题不仅会影响观众的观看体验&#xff0c;还会对视频品质产生负面影响。在调整播放速度时&#xff0c;要根据视频内容来进行调整。一般来说&#xff0c;…

双流网络论文精读笔记

精读视频&#xff1a;双流网络论文逐段精读【论文精读】_哔哩哔哩_bilibili Two-Stream Convolutional Networks for Action Recognition in Videos 传统的神经网络难以学习到物体的运动信息&#xff0c;双流网络则通过光流将物体运动信息抽取出来再传递给神经网络 给模型提供…

Qt 软件开发框架(主要部分)

目录 1、 一个软件基本要素 &#xff08;1&#xff09;UI模块 &#xff08;2&#xff09;网络模块 &#xff08;3&#xff09;业务逻辑模块 &#xff08;4&#xff09;中间层 &#xff08;5&#xff09;独立模块&#xff08;守护进程、更新模块、日志收集模块…&#xff…

蓝桥杯物联网竞赛_STM32L071_3_Oled显示

地位&#xff1a; 对于任何一门编程语言的学习&#xff0c;print函数毫无疑问是一种最好的调试手段&#xff0c;调试者不仅能通过它获取程序变量的运行状态而且通过对其合理使用获取程序的运行流程&#xff0c;更能通过关键变量的输出帮你验证推理的正确与否&#xff0c;朴素的…

Rust开发——数据对象的内存布局

枚举与Sized 数据 一般数据类型的布局是其大小&#xff08;size&#xff09;、对齐方式&#xff08;align&#xff09;及其字段的相对偏移量。 1. 枚举&#xff08;Enum&#xff09;的布局&#xff1a; 枚举类型在内存中的布局通常是由编译器来确定的。不同的编译器可能有不…

如何使用springboot服务端接口公网远程调试——实现HTTP服务监听

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;网络奇遇记、数据结构、算法模板 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 二. 内网穿透…

Java面试-微服务篇-SpringCloud

Java面试-微服务篇-SpringCloud SpringCloud 常见组件注册中心Eureka, Nacos负载均衡Ribbon服务雪崩, 熔断降级微服务的监控来源 SpringCloud 常见组件 通常情况下 Eureka: 注册中心Ribbon: 负载均衡Feign: 远程调用Hystrix: 服务熔断Zuul/Gateway: 网关 SpringCloudAlibaba…