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

news2024/9/23 21:22:08

目录

    • 什么是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.coloradmin.cn/o/1244325.html

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

相关文章

Django(十、中间件)

文章目录 一、中间件的介绍中间件有什么用中间件功能自定义中间中间件的顺序 一、中间件的介绍 中间件顾名思义,是介于request与response处理之间的一道处理过程,相对比较轻量级,并且在全局上改变django的输入与输出。因为改变的是全局&…

每日一练 | 华为认证真题练习Day136

1、OSI参考模型从高层到低层分别是? A. 应用层、会话层、表示层、传输层、网络层、数据链路层、物理层 B. 应用层、传输层、网络层、数据链路层、物理层 C. 应用层、表示层、会话层、传输层、网络层、数据链路层、物理层 D. 应用层、表示层、会话层、网络层、传…

Android : ExpandableListView(折叠列表) +BaseExpandableListAdapter-简单应用

示例图: 实体类DemoData.java package com.example.myexpandablelistview.entity;public class DemoData {private String content;private int img;public DemoData(String content, int img) {this.content content;this.img img;}public String getContent()…

1999-2021年地级市城镇居民人均消费性支出数据

1999-2021年地级市城镇居民人均消费性支出数据 1、时间:1999-2021年 2、指标:城镇居民人均消费性支出 3、范围:290个地级市 4、来源:城市年鉴、地级市统计公报 5、指标解释: 城镇居民人均消费性支出:指…

SpringBoot 导入其他配置文件

默认情况下,springboot 初始的项目中都有一个 application.yml 或者 application.properties 文件,如果我们希望再定义一个独立的配置文件用来配置特定业务数据,而不希望把这些配置内容都堆积在 application 配置文件中,实现这个需…

微电子专业词汇汇总,芯片人必备!

在芯片行业,很多相关的技术术语都是用英文表述。在这里为大家整理了一些常用的微电子专业词汇,希望对大家有所帮助。(文末可领全部文档) Abrupt junction 突变结 Accelerated testing 加速实验 Acceptor 受主 Acceptor atom 受主…

PS 注释工具 基础使用方法讲解

好 上文PS 颜色取样器&标尺工具 基本使用讲解中 我们讲了 颜色取样器和标尺工具的基本用法 下面我们来看一下 注释工具 这个 主要是后面 比较大的作品 可能不是我们一个人取设计 团队作图 就需要用到它 选择 注释工具 后 我们随便点击图像任何一个位置 右侧就会出现一个输…

Python 如何开发出RESTful Web接口,DRF框架助力灵活实现!

Django Rest Framework(DRF)是构建强大且灵活的Web API的优秀工具。它基于Django,提供了一套用于构建Web API的组件和工具,简化了API开发过程,同时保留了Django的优雅和强大。 一、Web应用模式 在开发Web应用时&…

边海防可视化智能视频监控与AI监管方案,助力边海防线建设

一、背景与需求 我国有3万多公里的边境线和海岸线,随着我国边海防基础设施建设的快速发展,边海安防也逐渐走向智能化。传统人工巡防的方式已经无法满足边海智能化监管的需求,在沿海、沿边地区进行边海智慧安防视频监控系统等边海防基础设施建…

深度学习卷积神经网络的花卉识别 计算机竞赛

文章目录 0 前言1 项目背景2 花卉识别的基本原理3 算法实现3.1 预处理3.2 特征提取和选择3.3 分类器设计和决策3.4 卷积神经网络基本原理 4 算法实现4.1 花卉图像数据4.2 模块组成 5 项目执行结果6 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 基…

手写promise(3)-- 实例方法 静态方法

目录 实例方法 catch finally 静态方法 reslove reject race all allSettled any 实例方法 提供给promise实例的方法 包括catch 与finally catch Promise 实例的 catch() 方法用于注册一个在 promise 被拒绝时调用的函数。它会立即返回一个等效的 Promise 对象&…

jjwt使用说明-笔记

jjwt官网链接&#xff1a;https://github.com/jwtk/jjwt POM 依赖 <dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.12.3</version> </dependency> <dependency><grou…

会议动态 | 祝贺2023 中国商品混凝土年会在上海隆重召开!

2023年11月19日-21日&#xff0c;由&#xff08;国家&#xff09;建筑材料工业技术情报研究所、中国散装水泥推广发展协会混凝土专委会主办的"笃信固本 行稳致远"——2023 第十九届全国商品混凝土可持续发展论坛暨2023中国商品混凝土年会在上海隆重召开&#xff01; …

什么是指针碰撞

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

Shell 通配符与正则表达元字符

Author&#xff1a;rab 目录 前言一、通配符1.1 *1.2 ?1.3 []1.4 {} 二、正则表达元字符2.1 *2.2 .2.3 ^2.4 $2.5 []2.6 \2.7 \<\>2.8 \{\} 总结 前言 不管是学任何语言&#xff0c;几乎都会涉及到通配符与正则的使用。有时候对于 Linux 初学者来说&#xff0c;往往会将…

线上问题排查实例分析|关于 Redis 内存泄漏

Redis 作为高性能的 key-value 内存型数据库&#xff0c;普遍使用在对性能要求较高的系统中&#xff0c;同时也是滴滴内部的内存使用大户。本文从 KV 团队对线上 Redis 内存泄漏定位的时间线维度&#xff0c;简要介绍 Linux 上内存泄漏的问题定位思路和工具。 16:30 问题暴露 业…

gitt开源项目的意义,公司为什么会对在gitt上有开源项目的人更大机会

Git是一种分布式版本控制系统&#xff0c;它可以帮助程序员管理代码的历史版本和协同工作。同时&#xff0c;Git也成为了开源项目的主要托管平台之一。Git的开源项目意义重大&#xff0c;因为这种开源项目托管平台可以帮助开发者将代码和项目分享给全球的开发者&#xff0c;并且…

linux网络之网络层与数据链路层

文章目录 一、网络层 1.IP协议 2.IP协议头格式 3.网段划分 4.特殊ip地址 5.IP地址的数量限制 6.私有ip和公网IP 7.路由 二、数据链路层 1.以太网 2.以太网帧格式 3.MAC地址 4.对比理解MAC地址和IP地址 5.MTU 6.ARP协议 ARP协议的工作流程 ARP数据报的格式 7.DNS 8.ICMP协议 9.N…

从六个方面对比Go和Python的差异

您是否想过 Go 与 Python 之间的主要区别是什么&#xff1f;随着对软件开发人员的需求不断增加&#xff0c;选择哪种编码语言可能会很困难。 ​ 在此&#xff0c;我们将从六个方面对比Go和Python,探讨 Go 和 Python之间的差异。我们将讨论它们的特点、优缺点&#xff0c;以便…

mongodb数据库的常用操作语句

说在前面的话 本文所有的操作示例&#xff0c;都以集合“HistoryTaskBase”为例。 一、查询 1、时间区间 查询“通知时间”介于2019-09-01到2019-10-01之间的数据。 db.getCollection(HistoryTaskBase).find({notifyTime:{$gte:ISODate(2019-09-01T00:00:00.000Z),$lte:ISOD…