IOS开发中数据持久化的几种方法--NSUserDefaults
IOS开发中数据持久化的几种方法--NSUserDefaults
IOS 开发中,经常会遇到需要把一些数据保存在本地的情况,那么这个时候我们有以下几种可以选择的方案:

一、使用NSUserDefault是最简单直接的一个办法:
1)保存数据:
// 实例化一个NSUserDefaults单例对象
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
// 把一个数组array保存在key为allContact的键值对里
[user setObject:array forKey:@"allContact"];
// 直接写入硬盘
[user synchronize];
2)读取数据:
// 实例化一个NSUserDefaults单例对象
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
// 把保存在里面的array根据key为allContact拿出来
NSArray *dataarray = [user objectForKey:@"allContact"];
注意事项:
在苹果的官方文档有明确说明:


也就是说,只能存入 NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary. For NSArray and NSDictionary objects, their contents must be property list objects.这些对象,而且(. For NSArray and NSDictionary objects, their contents must be property list objects.)比如数组,字典中存的元素也只能是以上这些对象的内容,那如何把自定义的一个比较复杂的类的实例对象使用NSUserDefaults保存呢?方法如下:
以一个手机联系人类myContact为例说明:
1)在myContact.h文件中让类遵守NSCoding协议:
//
// myContact.h
// 老年人电话本
//
// Created by mac on 16/5/3.
// Copyright © 2016年 mzw. All rights reserved.
// #import <Foundation/Foundation.h> //要使用单例NSUserDefault来存储自定义对象,首先要让自定义的对象遵守NSCoding协议
@interface myContact : NSObject<NSCoding> @property(nonatomic, copy)NSString *firstname;
@property(nonatomic, copy)NSString *lastname;
@property(nonatomic, copy)NSString *phoneNumber;
@property(nonatomic, copy)NSData *photo;
@property(nonatomic, copy)NSString *identify;
@property(nonatomic, assign)BOOL emergency; @end
2)在myContact.m文件中实现两个方法:encodeWithCoder 和 initWithCoder方法
//
// myContact.m
// 老年人电话本
//
// Created by mac on 16/5/3.
// Copyright © 2016年 mzw. All rights reserved.
// #import "myContact.h" @implementation myContact @synthesize firstname;
@synthesize lastname;
@synthesize phoneNumber;
@synthesize photo;
@synthesize identify;
@synthesize emergency; -(void)encodeWithCoder:(NSCoder *)aCoder{ [aCoder encodeObject:self.firstname forKey:@"firstname"];
[aCoder encodeObject:self.lastname forKey:@"lastname"];
[aCoder encodeObject:self.phoneNumber forKey:@"phoneNumber"];
[aCoder encodeObject:self.photo forKey:@"photo"];
[aCoder encodeObject:self.identify forKey:@"identify"];
[aCoder encodeBool:self.emergency forKey:@"emergency"];//注意对于布尔类型的不能使用encodeObject,而要对应的使用encodeBool。
} -(id)initWithCoder:(NSCoder *)aDecoder{ if (self = [super init]) { self.firstname = [aDecoder decodeObjectForKey:@"firstname"];
self.lastname = [aDecoder decodeObjectForKey:@"lastname"];
self.phoneNumber = [aDecoder decodeObjectForKey:@"phoneNumber"];
self.photo = [aDecoder decodeObjectForKey:@"photo"];
self.identify = [aDecoder decodeObjectForKey:@"identify"];
self.emergency = [aDecoder decodeBoolForKey:@"emergency"];//同理此处要对应的使用decodeBoolForKey。
}
return self;
}
3)完成以上两步,我们就可以通过NSUserDefaults来保存myContact的实例对象了:(以下程序段既涉及到读取,又涉及到追加内容后保存)
// 属性值赋值完成后就可以使用NSKeyedArchiver把对象mycontact1打包为一个NSData对象
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:mycontact1];
// 创建并初始化一个NSUserDefaults单例对象
NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
// 先读取user之前存进去的allContact所对应的值(是一个不可变的数组),然后因为我们要给这个数组追加一个联系人的打包后的NSData数据,所以要把这个数组转换成为一个可变数组。
NSMutableArray *contactarray = [NSMutableArray arrayWithArray:[user objectForKey:@"allContact"]];
// 把之前打包好的联系人mycontact1的NSData数据追加到可变数组contactarray中
[contactarray addObject:data];
// 再把这个可变数组转换为一个不可变数组
NSArray *array = [NSArray arrayWithArray:contactarray];
// 使用相同的key值保存新的array,之前allContact对应的值被替换
[user setObject:array forKey:@"allContact"];
// 直接写入硬盘
[user synchronize];
注意:通过NSUserDefaults保存的数据是全局的,这也为我们提供了一个管理全局变量的手段,比如在页面A保存了一些数据,在其他很多页面都要用到,那我们可以通过单例来保存,这样就可以在不同的页面中通过同个NSUserDefaults的key值去读取对应的内容。但这样的操作要注意,保存的数据一定是不可变的,不能是可变的数组、可变字符串、可变字典等,否则程序会产生不可预期的错误。
IOS开发中数据持久化的几种方法--NSUserDefaults的更多相关文章
- iOS开发中数据持久化
使用几个小例子分别实现 归档NSKeyedArchiver.NSUserDefaults.plist文件数据存储,简单直观.代码地址
- iphone开发中数据持久化之——属性列表序列化(一)
数据持久化是应用程序开发过程中的一个基本问题,对应用程序中的数据进行持久化存储,有多重不同的形式.本系列文章将介绍在iphone开发过程中数据持久化的三种主要形式,分别是属性列表序列号.对象归档化以及 ...
- iOS开发之动画编程的几种方法
iOS开发之动画编程的几种方法 IOS中的动画总结来说有五种:UIView<block>,CAAnimation<CABasicAnimation,CATransition,CAKe ...
- QF——iOS中数据持久化的几种方式
数据持久化的几种方式: 一.属性列表文件: .plist文件是种XML文件.数组,字典都可以和它互相转换.数组和字典可以写入本地变成plist文件.也可以读取本地plist文件,生成数组或字典. 读取 ...
- iphone开发中数据持久化之——嵌入式SQLite(三)
前两篇分别讨论了使用属性列表的数据持久化.使用对象归档的数据持久化,本文将讨论第三个实现数据持久化的方法---嵌入式SQL数据库SQLite3.SQLite3在存储和检索大量数据方面非常有效.它还能够 ...
- iOS开发中关于nslog的几种流行做法小结
不管哪种方法,都必须在PCH文件中做下宏定义 DEBUG和RELEASE要分开,RELEASE时log打印要取消 方法一:简单直接,用几行代码搞定,简洁但功能少 #ifdef DEBUG #defin ...
- iOS开发进阶-实现多线程的3种方法
相关文章链接: 1.多线程简介 2.实现多线程的3种方法 ......待续 前言 在多线程简介中,我已经说明过了,为了提高界面的流畅度以及用户体验.我们务必要把耗时的操作放到别的线程中去执行,千万不要 ...
- Hive开发中使用变量的两种方法
在使用hive开发数据分析代码时,经常会遇到需要改变运行参数的情况,比如select语句中对日期字段值的设定,可能不同时间想要看不同日期的数据,这就需要能动态改变日期的值.如果开发量较大.参数多的话, ...
- 哈希算法和字典类的定义,DataSet中数据遍历的几种方法
哈希算法的基本操作: 1. 哈希表(HashTable)简述 在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似 ...
随机推荐
- Python基础学习1---函数
Python函数篇 函数是重用的程序选, 他们允许给一块语句一个名称,然后可以在你的程序的任何地方是使用这个名称任意多次地运行这个语句块.这个就被称为 调用 函数.比如内建了很多高效的函数 如len ...
- 2016中国大学生程序设计竞赛 - 网络选拔赛 1001 A water problem (大数取余)
Problem Descripton Two planets named Haha and Xixi in the universe and they were created with the un ...
- html input密码显示为“*”
1. 功能需求:HTML中,在input password输入框中输入字符将默认显示为“实体圆点”,但这里要求将实体圆点字符替换成“*”号显示. 2. 局限:鼠标光标非IE浏览器不一定显示,选择多个字 ...
- discuz 添加板块失败解决办法
最近把服务器环境升了下级,发现discuz后台添加栏目添加不了了,数据库没变,源代码没变,就突然添加不了了.刚开始添加1个板块成功了,再添加就怎么也添不进去了.只是页面刷新了一下,啥提示没有. 经过一 ...
- Apache添加mime类型
今天同事给我提了一个bug,说IE浏览器无法下载网站上的固件版本文件(xxxx.img),点击下载后显示一堆二进制乱码,因为我们公司的固件版本文件是以.img结尾的,所以对应的content-type ...
- C#入门经典(2-重置窗体布局,界面介绍,错误列表)
- 手写js代码(一)javascript数组循环遍历之forEach
注:原文地址http://blog.csdn.net/oscar999/article/details/8671546 我这里是仿照学习! 1.js的数组循环遍历 ①数组的遍历首先想到的是for()循 ...
- 转 OGG add trandata 到底做了什么
有的时候我们做OGG的时候add trandata会出现异常. 这里就剖析一下add trandata到底做了什么 GGSCI (yjfora81 as ggs_admin@testdb) 2> ...
- Sonya and Problem Wihtout a Legend
Sonya and Problem Wihtout a Legend Sonya was unable to think of a story for this problem, so here co ...
- (转)Vim的Python编辑器详细配置过程 (Based on Ubuntu 12.04 LTS)
为什么要用vim编辑py文件? 因为在Linux命令行中,缺少图形界面的IDE,vim是最佳的文本编辑器,而为了更好的编辑py文本,所以配置vim. 1. 安装完整版vim vi和vim的区别? 在L ...