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命名空间提供的一个容器,用于处理和表现类似 ...
随机推荐
- Video Pooling
Video pooling computes video representation over the whole video by pooling all the descriptors from ...
- Boyer Moore算法(字符串匹配)
上一篇文章,我介绍了KMP算法. 但是,它并不是效率最高的算法,实际采用并不多.各种文本编辑器的"查找"功能(Ctrl+F),大多采用Boyer-Moore算法. Boyer-Mo ...
- hdu - 2586 How far away ?(最短路共同祖先问题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 最近公共祖先问题~~LAC离散算法 题目大意:一个村子里有n个房子,这n个房子用n-1条路连接起 ...
- android 5.1 API简介
android 5.1介绍: http://developer.android.com/about/versions/android-5.1.html?utm_campaign=lollipop-51 ...
- java工程开发之图形化界面之(第三课)
上面我们讲述了通过JOptionPane进行文本I/O操作,一个是通过JOptionPane来获取的 参考链接:http://blog.sina.com.cn/s/blog_993d254201013 ...
- hadoop伪分布式安装
hadoop的伪分布安装:一台实体机或虚拟机的安装. 环境:Windows7.VMWare.CentOS 1.1 设置ip地址 说明:在CentOS中的网络的类型: 仅主机模式:虚拟机在Windows ...
- SQL Server 索引维护sql语句
使用以下脚本查看数据库索引碎片的大小情况: 复制代码代码如下: DBCC SHOWCONTIG WITH FAST, TABLERESULTS, ALL_INDEXES, NO_INFOMSGS 以 ...
- opencv-jni -调试出错taking address of temporary [-fpermissive]
今天在进行代码往安卓平台移植时,IplImage *qImg=&(IplImage)dst1;报错taking address of temporary [-fpermissive] 百度了一 ...
- 模仿 app
原文链接:http://www.jianshu.com/p/a634b66cb180 前言 作为一个IOS程序员,闲的时候也想自己做一个app练练手,又苦于没有UI设计,也没有好的idea,所以只能先 ...
- C语言实现md5函数代码
网上找到的实现md5函数代码,包括一个头文件md5.h和一个源文件md5.c,用下面的测试代码test.c测试通过,各文件依次如下: 头文件md5.h #ifndef MD5_H #define MD ...