ios数据存储——对象归档
归档:数据从内存与闪存相互转化,类似“序列化”,将数据转换成二进制字节数据
操作:有两种方式,第一种是单个对象作为root进行归档和恢复,一个对象一个文件;第二种,可以同时归档多个对象到一个文件
注意:归档自定义对象,需要实现NSCoding协议里的两个方法,举例说明:【preference】http://blog.csdn.net/mad1989/article/details/9106475
一、创建一个数据模型(自定义类)
现在就以大家常见的Student的为例,这个模型有5个参数:name、age、weight、hobby、others
Student.h
- #import <Foundation/Foundation.h>
- @interface Student : NSObject<NSCoding,NSCopying>
- @property(copy,nonatomic) NSString *name;
- @property(assign,nonatomic) int age;
- @property(assign,nonatomic) double weight;
- @property(copy,nonatomic) NSArray *hobby;
- @property(copy,nonatomic) NSDictionary *others;
- @end
Student.m
- #import "Student.h"
- #define knameKey @"name"
- #define kageKey @"age"
- #define kweightKey @"weight"
- #define khobbyKey @"hobby"
- #define kotherKey @"others"
- @implementation Student
- @synthesize name;
- @synthesize age;
- @synthesize weight;
- @synthesize hobby;
- @synthesize others;
- #pragma mark-NSCoding
- -(void)encodeWithCoder:(NSCoder *)aCoder{
- [aCoder encodeObject:name forKey:knameKey];
- [aCoder encodeInt:age forKey:kageKey];
- [aCoder encodeDouble:weight forKey:kweightKey];
- [aCoder encodeObject:hobby forKey:khobbyKey];
- [aCoder encodeObject:others forKey:kotherKey];
- }
- -(id)initWithCoder:(NSCoder *)aDecoder{
- if (self == [super init]) {
- name = [aDecoder decodeObjectForKey:knameKey];
- age = [aDecoder decodeIntForKey:kageKey];
- weight = [aDecoder decodeDoubleForKey:kweightKey];
- hobby = [aDecoder decodeObjectForKey:khobbyKey];
- others = [aDecoder decodeObjectForKey:kotherKey];
- }
- return self;
- }
- #pragma mark-NSCopying
- -(id)copyWithZone:(NSZone *)zone{
- Student *copy = [[[self class] allocWithZone:zone] init];
- copy.name = [self.name copyWithZone:zone];
- copy.age = self.age;
- copy.weight = self.weight;
- copy.hobby = [self.hobby copyWithZone:zone];
- copy.others = [self.others copyWithZone:zone];
- return copy;
- }
- @end
通过以上的代码我们可以看出,要实现对数据模型的归档,需要我们实现NScoding协议,NScoping(copy协议是为了模型数据可以复制,对于归档而言,不是必须要实现)
NScoding协议需要实现两个方法:
-(void)encodeWithCoder:(NSCoder *)aCoder 以keyValue形式对基本数据类型Encoding
-(id)initWithCoder:(NSCoder *)aDecoder
以keyValue形式对基本数据类型Decoding,返回数据模型本身
-(id)copyWithZone:(NSZone *)zone NScopying协议的方法,目的为了实现数据模型的copy,如下实例:
- Student *s1 = [[Student alloc] init];
- Student *s2 = [s1 copy];
- NSLog(@"s1:%@",s1);
- NSLog(@"s2:%@",s2);
Log控制台输出:
2013-06-16 16:19:36.157 ArchiveDemo[1357:c07] s1:<Student: 0x8875340>
2013-06-16 16:19:36.158 ArchiveDemo[1357:c07] s2:<Student: 0x8875360>
二、ViewController.xib添加几个针对数据模型的可编辑组件:
三、接下来就是在Viewcontroller.m中的操作,首先添加一个内部使用的方法,返回要保存到闪存的位置:
- -(NSString *) getFilePath{
- NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- return [[array objectAtIndex:0] stringByAppendingPathComponent:kFileName];
- }
在ViewDidLoad方法里,每次viewController初始化时,读取路径下的归档文件,读取数据模型数据。同时添加一个通知每当按下Home键时,数据及时归档到闪存中。
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- if ([[NSFileManager defaultManager] fileExistsAtPath:[self getFilePath]]) {
- NSLog(@"filePAth:%@",[self getFilePath]);
- NSData *data = [[NSData alloc] initWithContentsOfFile:[self getFilePath]];
- NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
- //解档出数据模型Student
- Student *mStudent = [unarchiver decodeObjectForKey:kDataKey];
- [unarchiver finishDecoding];//一定不要忘记finishDecoding,否则会报错
- //接档后就可以直接使用了(赋值到相应的组件属性上)
- self.nameLabel.text = mStudent.name;
- self.ageLabel.text = [NSString stringWithFormat:@"%d",mStudent.age];
- self.weightLabel.text = [NSString stringWithFormat:@"%f",mStudent.weight];
- self.hobbyTextField.text = [mStudent.hobby objectAtIndex:0];
- self.othersTextView.text = [mStudent.others objectForKey:@"other"];
- [unarchiver release];
- [data release];
- }
- //添加一个广播,用于注册当用户按下home键时,归档数据到闪存中
- UIApplication *app = [UIApplication sharedApplication];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveAppDataWhenApplicationWillResignActive) name:UIApplicationWillResignActiveNotification object:app];
- }
四、某一操作需要保存数据的时候,及时归档到闪存中
- /**
- *当用户按下Home键,返回桌面时,归档当前数据到指定文件路径下
- */
- -(void) saveAppDataWhenApplicationWillResignActive:(NSNotification*) notification{
- Student *saveStudent = [[Student alloc] init];
- saveStudent.name = self.nameLabel.text;
- saveStudent.age = [self.ageLabel.text intValue];
- saveStudent.weight = [self.weightLabel.text doubleValue];
- saveStudent.hobby = [NSArray arrayWithObjects:self.hobbyTextField.text, nil];
- saveStudent.others = [NSDictionary dictionaryWithObjectsAndKeys:self.othersTextView.text,@"other",nil];
- NSMutableData *data = [[NSMutableData alloc] init];
- NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
- [archiver encodeObject:saveStudent forKey:kDataKey];
- [archiver finishEncoding];
- [data writeToFile:[self getFilePath] atomically:YES];
- [data release];
- [archiver release];
- [saveStudent release];
- }
运行效果:
重新运行后:
归档这种保存方式缺点就是没有属性列表(NSuserDefault)速度快,因为它每次都要把文件保存到闪存中,优点是可以创建自己想要的数据模型,然后统一以模型方式存储,比属性列表要过分依赖Key要省心。
ios数据存储——对象归档的更多相关文章
- IOS数据存储之归档/解档
前言: 前天学习了NSUserDefaults,我们知道NSUserDefaults不能保存自定义对象,所以我们今天来认识一下归档(NSKeyedArchiver)和解档(NSKeyedUnarchi ...
- iOS数据存储之对象归档
iOS数据存储之对象归档 对象归档 对象归档是iOS中数据持久化的一种方式. 归档是指另一种形式的序列化,但它是任何对象都可以实现的更常规的类型.使用对模型对象进行归档的技术可以轻松将复杂的对象写入文 ...
- iOS开发UI篇—ios应用数据存储方式(归档)
iOS开发UI篇—ios应用数据存储方式(归档) 一.简单说明 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦: 偏好设置(将所有的东西都保存在同 ...
- iOS开发UI篇—ios应用数据存储方式(归档) :转发
本文转发至:文顶顶http://www.cnblogs.com/wendingding/p/3775293.html iOS开发UI篇—ios应用数据存储方式(归档) 一.简单说明 在使用plist ...
- iOS数据存储之属性列表理解
iOS数据存储之属性列表理解 数据存储简介 数据存储,即数据持久化,是指以何种方式保存应用程序的数据. 我的理解是,开发了一款应用之后,应用在内存中运行时会产生很多数据,这些数据在程序运行时和程序一起 ...
- iOS数据存储类型 及 堆(heap)和栈(stack)
iOS数据存储类型 及 堆(heap)和栈(stack) 一般认为在c中分为这几个存储区: 1栈 -- 由编译器自动分配释放. 2堆 -- 一般由程序员分配释放,若程序员不释放,程序结束时可能由O ...
- iOS 数据持久性存储-对象归档
对象归档是将对象归档以文件的形式保存到磁盘中(也称为序列化,持久化),使用的时候读取该文件的保存路径读取文件的内容(也称为解档,反序列化) 主要涉及两个类:NSKeyedArichiver.NSKey ...
- ios应用数据存储方式(归档) - 转
一.简单说明 1.在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦. 2.偏好设置(将所有的东西都保存在同一个文件夹下面,且主要用于存储应用的设置 ...
- IOS 数据存储(NSKeyedArchiver 归档篇)
什么是归档 当遇到有结构有组织的数据时,比如字典,数组,自定义的对象等在存储时需要转换为字节流NSData类型数据,再通过写入文件来进行存储. 归档的作用 之前将数据存储到本地,只能是字符串.数组.字 ...
随机推荐
- 最简单的epoll的使用范例 : 监听 标准输入 ,并将数据回显到终端
#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<sys/epoll.h> # ...
- JavaBean,List,Map转成json格式
public class User { private String username; private String password; public String getUsername() { ...
- Windows API 之 CreateFile、CreateFileMapping 、MapViewOfFile
CreateFile Creates or opens a file or I/O device. The most commonly used I/O devices are as follows: ...
- logstash安装配置
vim /usr/local/logstash/etc/hello_search.conf 输入下面: input { stdin { type => "human" }} ...
- Java与C#的比较学习
http://www.cnblogs.com/javathread/archive/2012/08/11/2634893.html 我在大学学的是C语言,自学和选修的是C++,刚毕业也搞过几天Jsp, ...
- 苹果充电器USB端的识别电阻的设置
苹果为充电器定义了3种充电电流,分别是0.5A/1A/2.1A.具体是由3种不同的电阻组合来实现的.当苹果的设备ipad,iphone,ipod接入USB口充电器时,会先检测USB D+和D-上的电压 ...
- 判断非法字符串的类方法,与jsp
private String_do_judge judge; if (judge.isContain(key)) { return "feifa"; } 上面这写代码添加到进入ac ...
- 一段代码详解JavaScript面向对象
(function(){ //私有静态成员 var user = ""; //私有静态方法 function privateStaticMethod(){ } Box = func ...
- 阶乘相关<同余与模算术>
题意: 题目很简明: 令S[n]=1*1!+2*2!+3*3!+4*4!+....+n*n! 求S[n]%10000007 多组测试数据 每组一个n n的范围:1<=n<=1000000 ...
- HDU 1251 统计难题(字典树计算前缀数量)
字典树应用,每个节点上对应的cnt是以它为前缀的单词的数量 #include<stdio.h> #include<string.h> struct trie { int cnt ...