曾经接触过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保存内存中的对象的更多相关文章

  1. JavaScript 变量类型 保存内存中的位置 和 引用

    1. JavaScript变量 基本类型值在内存中占据固定大小的空间 因此被保存在栈内存中. 从一个变量向另一个变量复制基本来下的值 会创建这个值得一个副本. 引用类型的值是对象 保存在堆内存中. 包 ...

  2. 浅谈Java虚拟机内存中的对象创建,内存布局,访问定位

    参考于 深入理解Java虚拟机 这里介绍HotSpot虚拟机(自带的虚拟机) 1.对象的创建 对于程序员来说,创建对象的方法: User user1 = new User(); User user2 ...

  3. java内存中的对象

    前记:几天前,在浏览网页时偶然的发现一道以前就看过很多遍的面试题,题目是:“请说出‘equals’和‘==’的区别”,当时我觉得我还是挺懂的,在心里答了一点(比如我们都知道的:‘==’比较两个引用是否 ...

  4. 图解JVM在内存中申请对象及垃圾回收流程

    http://longdick.iteye.com/blog/468368 先看一下JVM的内存模型: 从大的方面来讲,JVM的内存模型分为两大块: 永久区内存( Permanent space )和 ...

  5. linq读书笔记2-查询内存中的对象

    上次我们说到了linq对数组内容的检索,自.net2.0以后,泛型成了很常见的一种应用技术,linq对泛型的检索也提供了完善的支持 如对list类型的支持,范例如下: class Program    ...

  6. 内存中 OLTP - 常见的工作负荷模式和迁移注意事项(二)

    ----------------------------我是分割线------------------------------- 本文翻译自微软白皮书<In-Memory OLTP – Comm ...

  7. PHP对象类型在内存中的分配

    对象类型和整型.字符串等类型一样,也是PHP中的一种数据类型.都是在程序中用于存储不同类型数据使用的,在程序运行时它的每部分内容都要先加载到内存中再被使用.那么对象类型的数据在内存中是如何分配的呢?先 ...

  8. java中的各种数据类型在内存中存储的方式

    原文地址:http://blog.csdn.net/aaa1117a8w5s6d/article/details/8251456 1.Java是如何管理内存的 java的内存管理就是对象的分配和释放问 ...

  9. 详解Python变量在内存中的存储

    这篇文章主要是对python中的数据进行认识,对于很多初学者来讲,其实数据的认识是最重要的,也是最容易出错的.本文结合数据与内存形态讲解python中的数据,内容包括: 引用与对象 可变数据类型与不可 ...

随机推荐

  1. maven+springMVC+mybatis+junit详细搭建过程 ***

    springMVC+mybatis框架搭建 在上一遍博客中以及讲诉了新建maven项目的流程,现在紧跟上一遍文章,接着搭建spring项目 首先我们先要弄清搭建项目的一般流程,需要注意哪些方面,想要什 ...

  2. Codeforces Round #363 (Div. 2)->B. One Bomb

    B. One Bomb time limit per test 1 second memory limit per test 256 megabytes input standard input ou ...

  3. C# Socket服务器端如何判断客户端断开

    使用Socket类中的Poll方法,就可以. Socket client //假如已经创建好了,连接到服务器端得Socket的客户端对象. 我们只要client.Poll(10,SelectMode. ...

  4. 01-08-04【Nhibernate (版本3.3.1.4000) 出入江湖】二级缓存:NHibernate自带的HashtableProvider之命名缓存

    http://www.cnblogs.com/lyj/archive/2008/11/28/1343418.html 可以在映射文件中定义命名查询,<query>元素提供了很多属性,可以用 ...

  5. java基础知识回顾之java Socket学习(二)--TCP协议编程

    TCP传输(传输控制协议):TCP协议是一种面向连接的,可靠的字节流服务.当客户端和服务器端彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能进行数据的传输.它将一台主机发出的字节流无差错的 ...

  6. Nodejs常见安装

    1.Windows 下成功安装node-canvas2.jsdom——node.js的DOM

  7. hdu 4418 Time travel 概率DP

    高斯消元求期望!! 将n时间点构成2*(n-1)的环,每一点的期望值为dp[i]=dp[i+1]*p1+dp[i+2]*p2+……+dp[i+m]*pm+1. 这样就可以多个方程,利用高斯消元求解. ...

  8. 深入理解JVM—字节码执行引擎

    原文地址:http://yhjhappy234.blog.163.com/blog/static/3163283220122204355694/ 前面我们不止一次的提到,Java是一种跨平台的语言,为 ...

  9. 李洪强iOS开发之OC[014] -对象的存储细节

    // //  main.m //  13 - 对象的存储细节 // //  Created by vic fan on 16/7/9. //  Copyright © 2016年 李洪强. All r ...

  10. Project Euler 93:Arithmetic expressions 算术表达式

    Arithmetic expressions By using each of the digits from the set, {1, 2, 3, 4}, exactly once, and mak ...