IOS数据存储之NSUserDefaults

Stella981
• 阅读 359

概述

数据存储是开发中必不可少的一个功能,我们可以通过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

点赞
收藏
评论区
推荐文章
Jacquelyn38 Jacquelyn38
1年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
刚刚好 刚刚好
4个月前
css问题
1、在IOS中图片不显示(给图片加了圆角或者img没有父级)<div<imgsrc""/</divdiv{width:20px;height:20px;borderradius:20px;overflow:h
blmius blmius
1年前
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
晴空闲云 晴空闲云
4个月前
css中box-sizing解放盒子实际宽高计算
我们知道传统的盒子模型,如果增加内边距padding和边框border,那么会撑大整个盒子,造成盒子的宽度不好计算,在实务中特别不方便。boxsizing可以设置盒模型的方式,可以很好的设置固定宽高的盒模型。盒子宽高计算假如我们设置如下盒子:宽度和高度均为200px,那么这会这个盒子实际的宽高就都是200px。但是当我们设置这个盒子的边框和内间距的时候,那
艾木酱 艾木酱
3个月前
快速入门|使用MemFire Cloud构建React Native应用程序
MemFireCloud是一款提供云数据库,用户可以创建云数据库,并对数据库进行管理,还可以对数据库进行备份操作。它还提供后端即服务,用户可以在1分钟内新建一个应用,使用自动生成的API和SDK,访问云数据库、对象存储、用户认证与授权等功能,可专
Wesley13 Wesley13
1年前
cobol学习之十数据库的增删改查模板
这次连接数据库使用的是ODBC连接access数据库,里面主要是一个增删改查的模板备份,方便以后查询。000001IDENTIFICATIONDIVISION.000002PROGRAMID.SAMPLEDB2.00
Easter79 Easter79
1年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
1年前
NSUserDefaults轻量级本地存储数据
NSUserDefaults适合存储轻量级的本地数据,比如要保存一个登陆界面的数据,用户名、密码之类的,个人觉得使用NSUserDefaults是首选。下次再登陆的时候就可以直接从NSUserDefaults里面读取上次登陆的信息咯。因为如果使用自己建立的plist文件什么的,还得自己显示创建文件,读取文件,很麻烦,而是用NSUserDefaults则不
helloworld_28799839 helloworld_28799839
4个月前
常用知识整理
Javascript判断对象是否为空jsObject.keys(myObject).length0经常使用的三元运算我们经常遇到处理表格列状态字段如status的时候可以用到vue
helloworld_34035044 helloworld_34035044
7个月前
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为