IOS数据存储之NSUserDefaults

Stella981
• 阅读 720

概述

数据存储是开发中必不可少的一个功能,我们可以通过Sqlite数据库手动创建数据库,定义数据表;可以使用IOS的数据框架CoreData,更方便的操作数据库;也可以直接读写文件系统;这里将介绍另外一种常用的方法:使用NSUserDefaults类,以字典形式保存数据,IOS会自动把字典中的键值对转换成对应的XML文件(也就是plist文件),这个文件会被保存到APP的沙盒目录中(路径为Library/Preferences/plist文件名)。

NSUserDefaults为我们封装了读写plist文件的常用操作,我们可以使用它来保存一些简单的数据,比如系统配置,用户设置的参数之类的。

了解plist文件

在学习使用NSUserDefaults类的用法前,我们需要先了解plist文件是一个什么文件,它是什么格式,可以保存哪些格式的数据。这样才能明白NSUserDefaults是干嘛用的!

当我们新建一个项目后,会发现有一个Info.plist文件,里面有很多参数配置:

IOS数据存储之NSUserDefaults

不要被这些复杂的参数所迷惑,这只是Xcode的为我们自动生成的一个plist文件,用来保存当前项目的一些配置,Xcode为它集成了很多可用的Key和Value,这些都是预置的。

我们所要了解一个文件的本质,只需使用文本编辑器打开plist文件(也可以使用Xcode自带的功能:右键plist文件,Open As,Source Code)。我用的是CotEditor:

IOS数据存储之NSUserDefaults

plist就是一个XML文件!key对应的就是键,string对应的就是值。

我们可以想像,NSUserDefaults为我们保存的就是这么一个xml文件,它的后缀名不叫xml而是plist,它会把我们代码中的Dictionary类型中的键值对转换成XML中对应的一个个节点。

plist中可以存储哪些数据类型

我们知道了plist是什么了之后,就该了解它的能力,也就是它能放哪些东西。

我们通过Xcode的plist文件编辑器,可以发现每一个键值对中间都有一个Type,不难理解这就是value的type,那有哪些type呢,右键即可:

IOS数据存储之NSUserDefaults

集合类型(Array、Dictionary)

基本数据类型:(Boolean、Date、Number、String)

对象数据类型:(Data)

不难理解,也就这些数据可以被转换保存到一个纯文本文件(区别于二进制文件)中,其中Data类型稍微复杂点,在代码中我们会把某一个代码转换换NSData类型,然后IOS再把NSData转换为一长串乱码保存。

集合和基本数据类型对应的数据类型相信各位都清楚。

使用NSUserDefaults保存读取数据

接下来,看下如何使用NSUserDefaults这个类。在dash中,输如NSUserDefaults,根据几个分节点,我们可以知道,读数据用xxForKey,写数据用Setxx,删数据用removeObjectForKey。

IOS数据存储之NSUserDefaults

可以看到,读方法中有很多不同类型的方法,我们可以根据不同的数据类型来选择使用的读取方法,写方法也类似。

我们选中其中一个方法,可以看到它是一个普通的func,不是类方法,也就是说,我们需要使用NSUserDefault类的实例来调用。

有2中方法,第一种就是使用构造函数init(),第二种是调用standardUserDefaults属性获得一个默认的对象。

两者区别是,创建plist文件时所使用的Domain,使用init构造函数时,不考虑Domain环境,直接在当前App的沙盒目录下创建plist文件,使用项目的bundle identifier字符串作为plist文件的文件名。

使用standardUserDefaults时考虑Domain环境,默认也是也是使用bundle identifier作为plist文件的文件名。另外支持NSGlobalDomain和NSRegistrationDomain,这一块就不详细展开了(因为我也还没理解...)

println(NSHomeDictionary())
let userDef = NSUserDefaults()
userDef.setInteger(1234, forKey: "count")
userDef.setObject("nice", forKey: "result")
userDef.setBool(true, forKey: "isShow")
userDef.setDouble(12.5, forKey: "point")

这段代码运行后,ios便会为我们创建一个plist文件,根据NSHomeDictionary方法返回的路径,打开目录,进入Library/Preferences目录:

IOS数据存储之NSUserDefaults

使用Xcode打开:

IOS数据存储之NSUserDefaults

写入数据,就这么简单,读取数据也同理:

println(userDef.integerForKey("count"))
 println(userDef.objectForKey("result"))
 println(userDef.boolForKey("isShow"))
 println(userDef.doubleForKey("point"))

IOS数据存储之NSUserDefaults

Data类型的保存

NSUserDefaults支持保存对象类型,前提是需要把对象转为NSData。

对象转换为NSData,我们把这个过程成为序列化或者叫编码~可以看这一篇详细介绍:《IOS中对象序列化与反序列化》

var person = Person()
person.name = "lijialong"
person.age = 26
let defa = NSUserDefaults()
//把Person对象保存到plist文件中,键值名为Person
defa.setObject(person, forKey: "Person")
defa.synchronize()

registerDefaults方法的使用

NSUserDefaults除了保存和读取功能外,还为我们提供了一个很便捷的方法:registerDefaults。

func registerDefaults(registrationDictionary: [NSObject : AnyObject])

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

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

let defa = NSUserDefaults()
//注册一个默认值
defa.registerDefaults(["firstRun":true])
//从plist文件中读取内容,因为第一次启动还没有生成plist文件,所以读取上面注册的默认值
let isFirstRun = defa.boolForKey("firstRun")
//是第一次启动
if(isFirstRun){
    
    println("这是第一次启动")
    //手动把firstRun改为false,保存到plist中
    defa.setBool(false, forKey: "firstRun")
}
else{
    println("不是第一次启动")
}

registerDefaults方法中的字典数据是不会被保存到plist文件中的,当我们读取某个键值时,如果plist中没有找到,那么会从registerDefaults方法的字典参数中寻找对应的键值,拿到默认值。当我们做了相应处理后,再手动把这个键值内容保存到plist中,下次读取是就会直接读plist文件中的键值了,而不会读取registerDefaults参数中的字典内容了。

tips:

本文由wp2blog导入,原文链接:http://devonios.com/nsuserdefaults.html

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表(关于日期时间时分秒显示不出来)
在使用皕杰报表设计器时,数据据里面是日期型,但当你web预览时候,发现有日期时间类型的数据时分秒显示不出来,只有年月日能显示出来,时分秒显示为0:00:00。1.可以使用tochar解决,数据集用selecttochar(flowdate,"yyyyMMddHH:mm:ss")fromtablename2.也可以把数据库日期类型date改成timestamp
Stella981 Stella981
3年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
(绝对有用)iOS获取UUID,并使用keychain存储
UDID被弃用,使用UUID来作为设备的唯一标识。获取到UUID后,如果用NSUserDefaults存储,当程序被卸载后重装时,再获得的UUID和之前就不同了。使用keychain存储可以保证程序卸载重装时,UUID不变。但当刷机或者升级系统后,UUID还是会改变的。但这仍是目前为止最佳的解决办法了,如果有更好的解决办法,欢迎留言。(我整理的解决办法的参
Stella981 Stella981
3年前
NSUserDefaults轻量级本地存储数据
NSUserDefaults适合存储轻量级的本地数据,比如要保存一个登陆界面的数据,用户名、密码之类的,个人觉得使用NSUserDefaults是首选。下次再登陆的时候就可以直接从NSUserDefaults里面读取上次登陆的信息咯。因为如果使用自己建立的plist文件什么的,还得自己显示创建文件,读取文件,很麻烦,而是用NSUserDefaults则不
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这