前言:做了一个图片浏览的小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写入失败??

分析思路: 查询方法注释,有这样一段话:

This method recursively validates that all the contained objects are property list objects 
(instances of NSData, NSDate, NSNumber, NSString, NSArray, or NSDictionary) before writing out the file,
 and returns NO if all the objects are not property list objects, since the resultant file would not be a valid property list.

这个方法在把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 和对象的序列化的更多相关文章

  1. C#对象先序列化然后反序列化时间丢失八小时的问题

    把对象JSON序列化,然后反序列化后发现时间少了八小时.因为在东八区,所以序列的时候按照1970-01-01:08:00:00为基数取得差值,而反序列化的时候以1970-01-01:00:00:00作 ...

  2. Java基础学习总结——Java对象的序列化和反序列化

    一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存 ...

  3. IO(四)----对象的序列化

    对象的序列化:   将内存中的对象直接写入到文件设备中. 对象的反序列化: 将文件设备中持久化的数据转换为内存对象. 自定义类只要实现了Serializable接口,便可以通过对象输入输出流对对象进行 ...

  4. Java对象的序列化和反序列化

    对象的序列化是指将对象转换为字节序列的过程 对象的反序列化是指将字节序列恢复对象的过程 主要有两种用途: 1.把对象的字节序列永久地保存在硬盘上,通常放在一个文件中. 2.在网络上传输对象的字节序列. ...

  5. Java对象的序列化

    1.概念 序列化:把Java对象转换为字节序列的过程. 反序列化:把字节序列恢复为Java对象的过程. 2.用途 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个 ...

  6. Qt持久性对象进行序列化

    Mfc和Java中自定义类的对象都可以对其进行持久性保存,Qt持久性对象进行序列化当然也是必不可少的.不过这个问题还真困扰了我很长时间……Mfc通过重写虚函数Serialize().Java则是所属的 ...

  7. iOS视图控制对象生命周期

    iOS视图控制对象生命周期-init.viewDidLoad.viewWillAppear.viewDidAppear.viewWillDisappear.viewDidDisappear的区别及用途 ...

  8. java对象的序列化与反序列化使用

    1.Java序列化与反序列化  Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程. 2.为什么需要序列化与反序列化 我们知道,当两个进程进 ...

  9. java中对象的序列化和反序列化

    [对象的序列化和反序列化 ] 1.定义:序列化--将对象写到一个输出流中.反序列化则是从一个输入流中读取一个对象.类中的成员必须是可序列化的,而且要实现Serializable接口,这样的类的对象才能 ...

随机推荐

  1. 自定义控件学习——仿qq侧滑栏

    效果 主要步骤: 1. 在xml布局里摆放内容. include    2. 在自定义ViewGroup里, 进行measure测量, layout布局    3. 响应用户的触摸事件    4. i ...

  2. Java Base64、HMAC、SHA1、MD5、AES DES 3DES加密算法

    ●  BASE64 严格地说,属于编码格式,而非加密算法    ●  MD5(Message Digest algorithm 5,信息摘要算法)    ●  SHA(Secure Hash Algo ...

  3. 七、Docker+nginx

    原文:七.Docker+nginx docker run -p 80:80 --name nginx-v1.0.0 -v /usr/nginx/www:/www -v /home/docker/ngi ...

  4. 建立一个 Openshift "Do-It-Yourself" 应用

    建立一个 Openshift "Do-It-Yourself" 应用 Openshift 的  "Do-It-Yourself" 就是自己可以编译定制 WEB ...

  5. 微信消息体加解密及EncodingAESKey

    公众平台消息体签名及加解密方案概述 1.新增消息体签名验证,用于公众平台和公众账号验证消息体的正确性 2.针对推送给微信公众账号的普通消息和事件消息,以及推送给设备公众账号的设备消息进行加密 3.公众 ...

  6. 00089_字节输出流OutputStream

    1.字节输出流OutputStream (1)OutputStream此抽象类,是表示输出字节流的所有类的超类.操作的数据都是字节,定义了输出字节流的基本共性功能方法: (2)输出流中定义都是写wri ...

  7. Dcloud开发webApp踩过的坑

    Dcloud开发webApp踩过的坑 一.总结 一句话总结:HTML5+扩展了JavaScript对象plus,使得js可以调用各种浏览器无法实现或实现不佳的系统能力,设备能力如摄像头.陀螺仪.文件系 ...

  8. 彻底搞懂HashMap,HashTable,ConcurrentHashMap之关联.

    注: 今天看到的一篇讲hashMap,hashTable,concurrentHashMap很透彻的一篇文章, 感谢原作者的分享.  原文地址: http://blog.csdn.net/zhange ...

  9. 用static 创建类的单例

    1.0 说明 通过函数调用new的static 类对象,由于static 对象只能初始化一次,由此构成单例运行. 2.0  直接代码 代码为windows,win32工程,因为只有一个文件,不上传工程 ...

  10. [WASM] Write to WebAssembly Memory from JavaScript

    We write a function that converts a string to lowercase in WebAssembly, demonstrating how to set the ...