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接口,这样的类的对象才能 ...
随机推荐
- 基于jQuery的楼层案例
~(function() { var flag = true; //点击切换效果 $(".oDR7_asideItem:not(:first)").click(function() ...
- BZOJ3620: 似乎在梦中见过的样子(KMP)
Description “Madoka,不要相信 QB!”伴随着 Homura 的失望地喊叫,Madoka 与 QB 签订了契约. 这是 Modoka 的一个噩梦,也同时是上个轮回中所发生的事.为了使 ...
- Core Animation 文档翻译—附录B(可动画的属性)
前言 许多CALayer和CIFliter的属性都是可动画的.本节附录列出了这些属性默认使用的动画. CALayer可动画属性 表B-1展示了CALayer类的可动画属性.针对每个属性此表 ...
- 4. Spring Boot 过滤器、监听器
转自:https://blog.csdn.net/catoop/article/details/50501688
- DriverModule_01
最小驱动模块: 最简单的Makefile 无配置文件 最小驱动的四部分 头文件 声明模块信息 模块驱动的入口.出口 功能区 关于这个头文件的分析: linux头文件的位置,例如#include< ...
- visual studio code 中 debugger for chrome 插件的配置
安装 debugger for chrome 插件后,把默认的 launch.json 改成: { "name": "谷歌浏览器", "type&qu ...
- 【例题 6-21 UVA - 506】System Dependencies
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 记录每个物品它的依赖有哪些,以及它被哪些东西依赖就可以了. 显式安装的东西不能被隐式删除删掉(就是remove item,然后删除i ...
- Dcloud课程5 php如何实现文件缓存技术(静态数据缓存)
Dcloud课程5 php如何实现文件缓存技术(静态数据缓存) 一.总结 一句话总结:保存在磁盘上的静态文件,用PHP生成数据到静态文件中.其实cookie和session使用的就是这样的技术,所以c ...
- [D3] Margin Convention with D3 v4
You can’t add axes to a chart if you don’t make room for them. To that end, the D3 community has ado ...
- 嵌入式Qt-4.8.6显示中文并且改变字体大小和应用自己制作的字体库
问题: QT4.8.6在移植到开发板上的时候,中文支持是必不可少的,如何让QT支持中文,如何制作QT支持的字体文件,如何使QT UI编辑器中的字号与开发板中的字号一致. 详解: 1>如何让QT支 ...