用NSData和NSFileManager保存内存中的对象
曾经接触过iOS开发,并且开发过两个应用,纵然青涩,也算是一断美好的回忆。转眼就已经一年多了!现在回过头来决定再次拿起iOS开发。
下面讲NSData:
NSdata的概念
1、使用文件时需要频繁地将数据读入一个临时存储区,它通常称为缓冲区
2、NSdata类提供了一种简单的方式,它用来设置缓冲区,将文件的内容读入缓冲区,或者将缓冲区内容写到一个文件。
3、对于32位应用程序,NSdata缓存最多2GB
4、我们有两种定义 NSData(不可变缓冲区),NSMutableData(可变缓冲区)
上面的描述有点片面,再补充一些:
NSData就是字节流的数据,它为字节流提供面向对象的存储空间,能够把一些字符串或图片等等一些非常复杂的数据类型转换成01字节流。在Objective-c中几乎所有的对象类型都可以转换成NSData(字符串也属于对象类型),基本数据类型需要先封装成对象,再转换成NSData。
在iOS中将对象序列化时,就需要将对象转换成为字节流数据即NSData类型的数据。
在要求将数据进行网络传输的场合,也需要将数据转化成为字节流才能进行传输。无论是向服务器写数据、还是从服务器返回的数据都应该是NSData类型的。
字定义保存内存中对象的方法
数据流图如下:
Object <-----> NSKeyedArchiver/NSKeyedUnarchiver <------> NSData <-----> NSString( file's name )
在Objective-c中要将对象转换成为NSData类型时,对象的类必须遵守NSCoding协议。NSCoding协议规定了两个必须实现的方法:initWithCoder:和encodeWithCoder:。initWithCoder:方法使用给定的状态初始化一个新对象,也称为反序列化,或者解码。encodeWithCoder:方法接收一个带状态的对象,并对其进行序列化,或者称为编码。您可以把encodeWithCoder:方法理解成将对象打包准备传输,把initWithCoder:方法理解成将接收到的数据解包成可用的对象。
许多常用的类,例如NSString、NSArray、NSNumber以及许多其他的类,已经实现了NSCoding协议。对于自定义的类,就需要用户自己实现NSCoding协议的initWithCoder:方法和encodeWithCoder:方法。这并不是很麻烦的事,可以看到一个实现NSCoding协议的例子:
@interface BigData : NSObject <NSCoding>
#pragma mark NSCoding
#define kTitleKey @"Title"
#define kRatingKey @"Rating" - (void) encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:_title forKey:kTitleKey];
[encoder encodeFloat:_rating forKey:kRatingKey];
} - (id)initWithCoder:(NSCoder *)decoder { NSString *title = [decoder decodeObjectForKey:kTitleKey];
float rating = [decoder decodeFloatForKey:kRatingKey];
return [self initWithTitle:title rating:rating]; }
在encodeWithCoder中,我们传入一个NSCoder对象,通过helper 方法把它编码成细小的数据片。这些helper方法有: encodeObject,encodeFloat,encodeInt等等。
在每一次encode的时候需要提供一个key用于以后decode的时候查找。通常,我们会对这些类加一个field,减一个field。为了让你的程序更健壮,在你decode一个field的时候,最好判断一下它的值是不是nil或者零,然后给它赋一个合适的默认值。
操作文件结构并保存
上代码,一个.m源文件:
#import "DataModel.h"
#import "NotePage.h" @implementation DataModel -(DataModel *)init{ [self loadPages];
return self;
} #pragma mark file storage
-(NSString*)documentsDirectory{ NSArray *paths =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [paths firstObject];
return documentsDirectory;
} -(NSString*)filePathOfPage:(NotePage *)page{ return [[self documentsDirectory]
stringByAppendingPathComponent:[NSString stringWithFormat:@"page%d.plist",page.pageID]]; } -(void)savePage:(NotePage *)page{ NSMutableData *data = [[NSMutableData alloc]init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver
alloc]initForWritingWithMutableData:data];
[archiver encodeObject:page forKey:[NSString stringWithFormat:@"page%d.plist",page.pageID] ];
[archiver finishEncoding];
[data writeToFile:[self filePathOfPage:page] atomically:YES];
} -(void)removePage:(NotePage *)page{ NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *path = [self filePathOfPage:page ];
NSError * error;
[fileManager removeItemAtPath:path error:&error];
int index = [self.pages indexOfObject:page];
[self.pages removeObjectAtIndex:index]; } -(void)loadPages{ self.pages = [[NSMutableArray alloc]initWithCapacity:];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *documentsPath = [self documentsDirectory];
NSError *error;
NSArray *fileList = [fileManager contentsOfDirectoryAtPath:documentsPath error:&error]; NSString *path;
NSData * data;
NSKeyedUnarchiver *unarchiver;
for (int i = ; i< fileList.count ; i++) {
if([[fileList[i] substringWithRange:NSMakeRange(, )] isEqualToString:@"page"]){
path = [documentsPath stringByAppendingPathComponent:fileList[i]];
data = [[NSData alloc]initWithContentsOfFile:path];
unarchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
NotePage *page = [unarchiver decodeObjectForKey:fileList[i]];
[self.pages addObject:page];
}
}
} @end
保存对象:
进程执行一个archiver对象中的方法,把对象编码成字节流保存到一个data对象中;然后执行data对象中的方法,把它保存的字节流写到一个文件中。
取出对象:
进程执行一个data对象中的方法,把文件中的字节流读出来;然后执行一个unarchiver对象中的方法,把data对象中的字节流解码还原成对象。
注意,编码和解码方法在要保存的对象内。
参考上文中的数据流图。
JAVA中的文件操作
数据流图如下:
BufferedReader <-------> InputStreamReader <-------> FileInputStream <------> File ( file's pointer )
ps:
另外博主找了一篇文章,算是概述的形式回顾一下iPhone开发吧! http://www.cnblogs.com/jy578154186/archive/2013/02/27/2934881.html
用NSData和NSFileManager保存内存中的对象的更多相关文章
- JavaScript 变量类型 保存内存中的位置 和 引用
1. JavaScript变量 基本类型值在内存中占据固定大小的空间 因此被保存在栈内存中. 从一个变量向另一个变量复制基本来下的值 会创建这个值得一个副本. 引用类型的值是对象 保存在堆内存中. 包 ...
- 浅谈Java虚拟机内存中的对象创建,内存布局,访问定位
参考于 深入理解Java虚拟机 这里介绍HotSpot虚拟机(自带的虚拟机) 1.对象的创建 对于程序员来说,创建对象的方法: User user1 = new User(); User user2 ...
- java内存中的对象
前记:几天前,在浏览网页时偶然的发现一道以前就看过很多遍的面试题,题目是:“请说出‘equals’和‘==’的区别”,当时我觉得我还是挺懂的,在心里答了一点(比如我们都知道的:‘==’比较两个引用是否 ...
- 图解JVM在内存中申请对象及垃圾回收流程
http://longdick.iteye.com/blog/468368 先看一下JVM的内存模型: 从大的方面来讲,JVM的内存模型分为两大块: 永久区内存( Permanent space )和 ...
- linq读书笔记2-查询内存中的对象
上次我们说到了linq对数组内容的检索,自.net2.0以后,泛型成了很常见的一种应用技术,linq对泛型的检索也提供了完善的支持 如对list类型的支持,范例如下: class Program ...
- 内存中 OLTP - 常见的工作负荷模式和迁移注意事项(二)
----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<In-Memory OLTP – Comm ...
- PHP对象类型在内存中的分配
对象类型和整型.字符串等类型一样,也是PHP中的一种数据类型.都是在程序中用于存储不同类型数据使用的,在程序运行时它的每部分内容都要先加载到内存中再被使用.那么对象类型的数据在内存中是如何分配的呢?先 ...
- java中的各种数据类型在内存中存储的方式
原文地址:http://blog.csdn.net/aaa1117a8w5s6d/article/details/8251456 1.Java是如何管理内存的 java的内存管理就是对象的分配和释放问 ...
- 详解Python变量在内存中的存储
这篇文章主要是对python中的数据进行认识,对于很多初学者来讲,其实数据的认识是最重要的,也是最容易出错的.本文结合数据与内存形态讲解python中的数据,内容包括: 引用与对象 可变数据类型与不可 ...
随机推荐
- JavaScript高级---装饰者模式设计
一.设计模式 javascript里面给我们提供了很多种设计模式: 工厂.桥.组合.门面.适配器.装饰者.享元.代理.观察者.命令.责任链 在前面我们实现了工厂模式和桥模式 工厂模式 : 核心:为了生 ...
- NOI 国家集训队论文集
鉴于大家都在找这些神牛的论文.我就转载了这篇论文合集 国家集训队论文分类 组合数学 计数与统计 2001 - 符文杰:<Pólya原理及其应用> 2003 - 许智磊:<浅谈补集转化 ...
- Unity3D开发(五):Unity3D 4.x 使用Mecanim实现连击(转)
原地址:http://www.unitymanual.com/blog-1801-1221.html unity3d 4.x 版本之后提供了一种新的动画机制Mecanim,虽然目前还支持之前的Anim ...
- POJ 2253 Frogger(floyd)
http://poj.org/problem?id=2253 题意 : 题目是说,有这样一只青蛙Freddy,他在一块石头上,他呢注意到青蛙Fiona在另一块石头上,想去拜访,但是两块石头太远了,所以 ...
- hdu 3595 GG and MM 博弈论
同时进行,必须操作这就是Every-SG的特点 同样在贾志豪的论文中有提到这种游戏:组合游戏略述——浅谈SG游戏的若干拓展及变形 其中这个游戏特点不仅有必胜和必败,而且有时间长短的博弈,对于自己必胜的 ...
- lintcode : 平衡二叉树
题目 平衡二叉树 给定一个二叉树,确定它是高度平衡的.对于这个问题,一棵高度平衡的二叉树的定义是:一棵二叉树中每个节点的两个子树的深度相差不会超过1. 样例 给出二叉树 A={3,9,20,#,#,1 ...
- yum工具介绍
当你的linux处于联网状态时,yum工具能够非常方便的在Linux上安装各种软件.补丁等等,而且最重要的一点是完全不用管包的依赖关系.只需要简单的指定你要安装的软件名称,其他工作几乎都交给yum了, ...
- Google不做坏事吗?
说中国足球为什么冲不出亚洲,那是因为咱中国人太文气,足球是种“斗牛士”式的游戏,得玩的有点儿“野蛮”色彩.记得以前在英国的时候,遇上联赛,晚上大街小巷全民皆兵,曼切斯特队的粉丝在街道一边酒吧里,利物浦 ...
- 使用List,Dictionary加载数据库中的数据
情景描述:数据库中有一张设备表,字段DWDM存放的是各个厂编号,字段ZNBH存放的是设备编号.其中DWDM跟ZNBH是一对多的关系.需要将数据库中的值加载到List<Dictionary< ...
- set集合_定长
//set集合的操作 //便利初始化函数 NSSet *set1 = [[NSSet alloc] initWithObjects:@"aa", @&q ...