iOS writeTofile 和对象的序列化
前言:做了一个图片浏览的小demo,支持随意添加、删除图片,图片放大、缩小,带矩形框的截图。随后几篇博客都会详细讲解在此过程中遇到的各种问题。这篇主要讲,在做添加、删除这个功能时,遇到的存文件的问题。
我们想实现在以后每次打开这个程序时,不用再一张张手动添加,而会保留用户上次已经选择的图片,那么就需要把这些图片存入内存,每次从内存中读取。
正文:
一、存文件有几种方式?
直接写入FILE、对象序列化
二、直接写入FILE
在我的程序里,我是把图片都存在一个NSMutableDictionary,每个image都对应一个key。
1、直接调用NSDictionary的writeToFile:atomically:方法,将dic存入一个指定的目录。
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flagDescription
功能:Writes a property list representation of the contents of the dictionary to a given path.
把一个代表这个dictionary内容的property列表写入到指定的路径。
出现问题:目录创建没有问题,但是一直writeToFile写入失败??
分析思路: 查询方法注释,有这样一段话:
这个方法在把dic写入文件之前,会递归的验证所有包含的对象是否都是property列表里的对象(包括 NSData, NSDate, NSNumber, NSString, NSArray, or NSDictionary)。
如果dic中所有的对象不全是property列表里的对象,那么返回NO,因为最后生成的文件不是一个有效的 property list.
失败原因:是因为我的dic中存的obj是UIImage,不属于property list,所以返回失败。
解决办法:把UIImage换成property list里的对象NSData,把NSData存入dic中。
NSData *data = UIImagePNGRepresentation(img);
2、从FILE中取出
在writeToFile的注释中,写到:If the dictionary’s contents are all property list objects, the file written by this method can be used to initialize a new dictionary with the class method dictionaryWithContentsOfFile: or the instance method initWithContentsOfFile:.
如果这个dic的内容都是property list,那么通过这个方法写的文件可以用来初始化一个新的dictionary,方法:dictionaryWithContentsOfFile:或者initWithContentsOfFile:.
NSMutableDictionary *dic= [NSMutableDictionary dictionaryWithContentsOfFile:_filePath];
问题:在写入成功后,我调用这个dictionaryWithContentsOfFile时,得到的新dic总是有问题。
分析原因:写入问题?参数_filePath问题?写入如果有问题的话,那么根本就不会成功,换了一个新的path成功了,说明是 _filePath的问题。在失败的打印框中输入po _filePath,果然是个空指针。这个问题是我怎么都没有想到的。我把_filePath定为全局变量,在一开始的init方法中,就给它赋了值,可 是这里它怎么会是nil了??
来看一下我的赋值方法:
_filePath = [NSString stringWithFormat:@"%@/Documents/imageViews/test.plist",NSHomeDirectory()];
现在知道问题出在哪了吧?!!在前面的博客中详细分析过这个问题,凡是没有用alloc等方法构造的对象,如果在程序的其他地方还要用的话,一定要加上retain!!!
修改后一切ok!
三、对象序列化
在接触新内容时,我们先来回顾一下java的对象序列化。在java中,需要序列化的对象必须实现Serializable接口,通过调用writeObject、readObject这两个方法存储、读取对象。
在oc中,也是类似的。需要序列化的对象必须实现NSCoding协议并重写encodeWithCoder和initWithCoder两个方法,分别用以编码和反编码,通过调用NSKeyedArchiver、NSKeyedUnarchiver这两个类来存储、读取对象。如果继承的类已经实现了NSCoding协议,那么子类就不用实现了。
[NSKeyedArchiver archiveRootObject:obj toFile:filename]; //序列化
obj = [NSKeyedUnarchiver unarchiveObjectWithFile: filename]; //反序列化
因为目前还没有尝试,就简单介绍一下,用到的时候再详细研究。可参考:http://blog.csdn.net/holydancer/article/details/7371643
四、总结
1、writeToFile方法,只适用于 NSData, NSDate, NSNumber, NSString, NSArray, or NSDictionary这些类。
2、我们自定义的类要写入文件,都是用序列化方法。
iOS writeTofile 和对象的序列化的更多相关文章
- C#对象先序列化然后反序列化时间丢失八小时的问题
把对象JSON序列化,然后反序列化后发现时间少了八小时.因为在东八区,所以序列的时候按照1970-01-01:08:00:00为基数取得差值,而反序列化的时候以1970-01-01:00:00:00作 ...
- Java基础学习总结——Java对象的序列化和反序列化
一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存 ...
- IO(四)----对象的序列化
对象的序列化: 将内存中的对象直接写入到文件设备中. 对象的反序列化: 将文件设备中持久化的数据转换为内存对象. 自定义类只要实现了Serializable接口,便可以通过对象输入输出流对对象进行 ...
- Java对象的序列化和反序列化
对象的序列化是指将对象转换为字节序列的过程 对象的反序列化是指将字节序列恢复对象的过程 主要有两种用途: 1.把对象的字节序列永久地保存在硬盘上,通常放在一个文件中. 2.在网络上传输对象的字节序列. ...
- Java对象的序列化
1.概念 序列化:把Java对象转换为字节序列的过程. 反序列化:把字节序列恢复为Java对象的过程. 2.用途 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个 ...
- Qt持久性对象进行序列化
Mfc和Java中自定义类的对象都可以对其进行持久性保存,Qt持久性对象进行序列化当然也是必不可少的.不过这个问题还真困扰了我很长时间……Mfc通过重写虚函数Serialize().Java则是所属的 ...
- iOS视图控制对象生命周期
iOS视图控制对象生命周期-init.viewDidLoad.viewWillAppear.viewDidAppear.viewWillDisappear.viewDidDisappear的区别及用途 ...
- java对象的序列化与反序列化使用
1.Java序列化与反序列化 Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程. 2.为什么需要序列化与反序列化 我们知道,当两个进程进 ...
- java中对象的序列化和反序列化
[对象的序列化和反序列化 ] 1.定义:序列化--将对象写到一个输出流中.反序列化则是从一个输入流中读取一个对象.类中的成员必须是可序列化的,而且要实现Serializable接口,这样的类的对象才能 ...
随机推荐
- Servlet简单注解方式使用
我们是用Servlet进行跳转的时候都需要去web.xml中进行配置,分繁琐. 那么今天就学习下使用注解方式配置servlet一样好使 package com.shxt.servlet; import ...
- tab标签页(选项卡)插件
<body style="margin: 50px;"> <ul id="nav" class="nav nav-tabs" ...
- js-轮播图的总结
/*两种播放行为:(一种自动播放,一种控制播放),一个定时器控制. *一个定时器控制两种播放状态. * 布局说明:装图片的盒子足够宽,让图片左浮,排成一排,最后一张重新放置第一张. * 定时器里执行自 ...
- bzoj3786星系探索(splay维护dfs序)
Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球 ...
- http 500 Internal Server Error的错误 ajax请求SpringMVC后台中返回500 Internal Server Error
使用httprequester接口测试能返回数据,但是用ajax返回json格式的时候返回报500Internal Server Error. The server encountered an in ...
- ES5比较Jquery中的each与map 方法?
1.each es5: var arr = [1, 5, 7, 8, 9];var arr1 = []; arr.forEach(function (v, i) { arr1.push(v * 4) ...
- 【例题 7-8 UVA - 10603】Fill
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 三维显然可以缩短为2维. 只要知道a,b瓶中的水量,c瓶中的水量减一下就能得到. 则设dis[a][b]表示a,b瓶中水量为a,b时 ...
- ajax 通过return 返回data值
方法例如以下: 1. ajax 必须为同步 设置async:false 2. 定一个局部变量 把data赋值给局部变量 然后 return 局部变量就可以 示比例如以下 function getEmp ...
- git各种命令 & git merge和git rebase的区别
git merge 和 rebase的区别: http://blog.csdn.net/jollyjumper/article/details/24743751 对于两个分支而言,rebase和mer ...
- MySql开发之函数
1,在mySql常见的文本函数中常见的文本函数例如以下表所看到的: 2,数字函数例如以下: 3,日期和时间函数: 4,格式化日期和时间 使用的函数例如以下DATE_FORMAT()和TIME_FORM ...