前言:做了一个图片浏览的小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. java中异常的限制

    子类在覆盖父类方法时,父类的方法如果抛出了异常,那么子类的方法只能抛出父类的异常或者该异常的子类.如果父类抛出多个异常,那么子类只能抛出父类异常的子集.简单说:子类覆盖父类只能抛出父 ...

  2. Linux shell command学习笔记(一)

    Shell的种类有很多种,例如CSH,Bourne Shell,Korn Shell.在现在的大多数Linux发行版中,默认的Shell一般都是Bourne again shell(bash). &l ...

  3. [CortexM0--stm32f0308]discovery开发板

        问题描写叙述:stm32提供了很多IC入门级开发板,价格还是蛮廉价的. stm32f0308-discovery就是一款cortex-m0架构的入门级开发板. 例如以下对其进行下简介. IO便 ...

  4. 《从零開始学Swift》学习笔记(Day 59)——代码排版

    原创文章,欢迎转载.转载请注明:关东升的博客 代码排版包括: 空行.空格.断行和缩进等内容.代码排版内容比較多工作量非常多.可是非常重要. 空行 空行将逻辑相关的代码段分隔开.以提高可读性. 下列情况 ...

  5. android-5.1编译配置(van)

    必备文件: archives1211.tgz ubuntu_install_1204.tgz 安装指引: ubuntu_install_1204/readme.txt 工作目录结构: git ├── ...

  6. 14.inline与namespace使用

    #include <iostream> using namespace std; namespace all { //inline作用为默认调用 inline namespace V201 ...

  7. IOS系统不兼容position: fixed;属性的解决方案

    position: fixed;属性在IOS系统手机上会有很明显的抖动,解决方式: 只需要在中间部分外层div添加css样式position:fixed;top:50px; bottom:50px;o ...

  8. datetime小练习

    题目: 1.计算你的生日比如近30年来(1990-2019),每年的生日是星期几,统计一下星期几出现的次数比较多2,生日提醒,距离生日还有几天 # !/usr/bin/env python # -*- ...

  9. ClickOnce

    Clic WPF ClickOnce应用程序IIS部署发布攻略   WPF程序非常适合公司内网使用,唯一缺点就是客户端要安装.net框架4.0.优势也很明显,在客户端运行的是一个WinForm程序,自 ...

  10. 洛谷 P1657 选书

    P1657 选书 题目描述 学校放寒假时,信息学奥赛辅导老师有1,2,3……x本书,要分给参加培训的x个人,每人只能选一本书,但是每人有两本喜欢的书.老师事先让每个人将自己喜欢的书填写在一张表上.然后 ...