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"];

注意事项:

在苹果的官方文档有明确说明:

也就是说,只能存入 NSDataNSStringNSNumberNSDateNSArray, 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的更多相关文章

  1. iOS开发中数据持久化

    使用几个小例子分别实现 归档NSKeyedArchiver.NSUserDefaults.plist文件数据存储,简单直观.代码地址

  2. iphone开发中数据持久化之——属性列表序列化(一)

    数据持久化是应用程序开发过程中的一个基本问题,对应用程序中的数据进行持久化存储,有多重不同的形式.本系列文章将介绍在iphone开发过程中数据持久化的三种主要形式,分别是属性列表序列号.对象归档化以及 ...

  3. iOS开发之动画编程的几种方法

    iOS开发之动画编程的几种方法 IOS中的动画总结来说有五种:UIView<block>,CAAnimation<CABasicAnimation,CATransition,CAKe ...

  4. QF——iOS中数据持久化的几种方式

    数据持久化的几种方式: 一.属性列表文件: .plist文件是种XML文件.数组,字典都可以和它互相转换.数组和字典可以写入本地变成plist文件.也可以读取本地plist文件,生成数组或字典. 读取 ...

  5. iphone开发中数据持久化之——嵌入式SQLite(三)

    前两篇分别讨论了使用属性列表的数据持久化.使用对象归档的数据持久化,本文将讨论第三个实现数据持久化的方法---嵌入式SQL数据库SQLite3.SQLite3在存储和检索大量数据方面非常有效.它还能够 ...

  6. iOS开发中关于nslog的几种流行做法小结

    不管哪种方法,都必须在PCH文件中做下宏定义 DEBUG和RELEASE要分开,RELEASE时log打印要取消 方法一:简单直接,用几行代码搞定,简洁但功能少 #ifdef DEBUG #defin ...

  7. iOS开发进阶-实现多线程的3种方法

    相关文章链接: 1.多线程简介 2.实现多线程的3种方法 ......待续 前言 在多线程简介中,我已经说明过了,为了提高界面的流畅度以及用户体验.我们务必要把耗时的操作放到别的线程中去执行,千万不要 ...

  8. Hive开发中使用变量的两种方法

    在使用hive开发数据分析代码时,经常会遇到需要改变运行参数的情况,比如select语句中对日期字段值的设定,可能不同时间想要看不同日期的数据,这就需要能动态改变日期的值.如果开发量较大.参数多的话, ...

  9. 哈希算法和字典类的定义,DataSet中数据遍历的几种方法

    哈希算法的基本操作: 1.  哈希表(HashTable)简述   在.NET Framework中,Hashtable是System.Collections命名空间提供的一个容器,用于处理和表现类似 ...

随机推荐

  1. myEclipse JSP 调用 IDL8.2 配置

    新安装了Envi5.0 IDL8.2,路径改动了,一些配置也要随之改动.现在总结一下,JSP调用IDL的配置. jar包配置,环境变量配置,dll配置,tomcat路径配置,tomcat运行选项配置, ...

  2. PHPer转战Android的学习过程以及Android学习

    原文作者: eoeadmin原文地址: http://my.eoe.cn/shuhai/archive/19684.html-------------------------------------- ...

  3. 空间表SpaceList

    比如在建一个成绩管理系统,这时候定义的名字一般都是char szName[20],这样比较浪费,其实不只是定义名字,定义好多变量都这样,并没有体现动态. 此处出现空间表(SpaceList),通过指针 ...

  4. java开发地三天——数据库介绍

    又是一天萌萌哒地过去了,今天是处理数据库的部分.SQL Server 2008,这东西是上学期搞MFC的时候接触到的,那时候话说安装就是一个大问题,然后在学SQL语句的时候感觉还好,一切都还过得去.现 ...

  5. 对比C#中==与equal方法

    C#中equal与==的区别 收藏 对于值类型,如果对象的值相等,则相等运算符 (==) 返回 true,否则返回 false.对于string 以外的引用类型,如果两个对象引用同一个对象,则 == ...

  6. iOS开发-正则表达式3种形式

    转至:http://www.cnblogs.com/GarveyCalvin/p/4250145.html iOS开发-正则表达式的使用方法 前 言:在表单验证中,我们经常会使用到正则,因为我们需要用 ...

  7. 我也谈javascript闭包

    1.什么是闭包呢?Whenever you see the function keyword within another function, the inner function has acces ...

  8. 4个特殊ping

    当你的网络出现故障或无法连通时,如何才能简单高效的找出故障?其实只需要一个ping命令,就可以判断TCP/IP协议故障…… 1.Ping 127.0.0.1: 127.0.0.1是本地循环地址,如果本 ...

  9. Linux服务器自动备份压缩MySQL数据库的实用方法

    <?php$server = 'localhost'; $link = mysql_connect($server, 'root', 'haven'); $result = mysql_quer ...

  10. HDU 5438 拓扑排序+DFS

    Ponds Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Sub ...