软件中永远绕不开的一个问题就是数据存储的问题,PC的时候一般都是选择在数据库中存储,iOS如果是和后端配合的话,那么不需要考虑数据存储的这个问题,上次写了一下plist的存储,不过数据都是存储一些简单的键值对对象。本次需要将一些自己定义的类型存储在plist比如说图片,这个时候可以利用NSCoding协议,将数据地以类似档案的形式存储到plist文件中,然后从plist的文件中读取数据,使用协议的时候这个时候就会用到了NSCoder,如果对存档和解压没有概念的话,可以简单的理解为数据的序列化与反序列化。

基础概念

NSCoding是一个protocol. 如果实现了NSCoding,需要实现其中的两个方法:

1
2
- (void)encodeWithCoder:(NSCoder *)aCoder;
- (id)initWithCoder:(NSCoder *)aDecoder; // NS_DESIGNATED_INITIALIZER

方法中的主要的参数就是NSCoder,它是archivie字节流的抽象类.可以将数据写入一个coder,也可以从coder中读取我们写入的数据. NSCoder是一个抽象类,不能直接使用它来创建对象. 但是可以通过其子类NSKeyedUnarchiver从字节流中读取数据,NSKeyedArchiver将对象写入到字节流。本文以书籍为例:

新建一个Book类,Book.h中的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
 
@interface Book : NSObject<NSCoding>
 
@property (strong,nonatomic) UIImage *ConverPicture;
 
@property (strong,nonatomicNSString *BookName;
 
@property (strong,nonatomicNSString *Author;
 
@property (strong,nonatomicNSNumber *Price;
 
@end

Book.m中实现NSCoding的两个方法,注意中UIImage的写法与其他有所不同:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@implementation Book
 
- (void)encodeWithCoder:(NSCoder *)aCoder{
     
    //注意这里是存储的是JPG图片的调用
    [aCoder encodeObject:UIImageJPEGRepresentation(self.ConverPicture,1.0)forKey:@"ConverPicture"];
    [aCoder encodeObject:_BookName forKey:@"BookName"];
    [aCoder encodeObject:_Author forKey:@"Author"];
    [aCoder encodeObject:_Price forKey:@"Price"];
     
}
 
- (id)initWithCoder:(NSCoder *)aDecoder{
     
    self.ConverPicture=[UIImage imageWithData:[aDecoder decodeObjectForKey:@"ConverPicture"]];
    self.BookName=[aDecoder decodeObjectForKey:@"BookName"];
    self.Author=[aDecoder decodeObjectForKey:@"Author"];
    self.Price=[aDecoder decodeObjectForKey:@"Price"];
    return self;
     
}
@end

Demo实现

正常的情况的不需要新建页面的,不过需要演示一下UIImage的效果,Main.storyboard中的布局:

稍微解释一下,前两个是存的单文件,后两个存的是多文件,UIImage展示存储的图片:

ViewController定义字段:

1
2
3
4
5
@property (strong,nonatomicNSString *storagePath;
 
@property (strong,nonatomicNSString *storageListPath;
 
@property (strong,nonatomicNSMutableArray *bookList;

设置路径,如果不是很清晰,可参考本文之前的博客:

1
2
3
4
NSArray *codepath= NSSearchPathForDirectoriesInDomains(NSDocumentDirectoryNSUserDomainMaskYES);
  _storagePath = [codepath[0] stringByAppendingPathComponent:@"book.plist"];
      NSLog(@"%@",NSHomeDirectory());
  _storageListPath = [codepath[0] stringByAppendingPathComponent:@"booklist.plist"];

 单个存档:

1
2
3
4
5
6
7
8
9
Book *book=[[Book alloc]init];
   UIImage *image=[UIImage imageNamed:@"Code1.jpg"];
   book.ConverPicture=image;
   book.BookName=@"百年孤独";
   book.Author=@"加西亚.马尔克斯";
   book.Price=[[NSNumber alloc] initWithInteger:45];
   if ([NSKeyedArchiver archiveRootObject:book toFile:_storagePath]) {
       NSLog(@"数据存档成功");
   }

 单个解压:

1
2
3
4
5
Book *decodeBook=[NSKeyedUnarchiver unarchiveObjectWithFile:_storagePath];
  self.myImageView.image=decodeBook.ConverPicture;
     NSLog(@"%@",decodeBook.ConverPicture);
  NSLog(@"%@",decodeBook.BookName);
  NSLog(@"解档成功");

 多个存档:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
self.bookList=[NSMutableArray array];
  for (NSInteger i=1; i<3; i++) {
      Book *book=[[Book alloc]init];
      NSString *imageName=[NSString stringWithFormat:@"Code%ld.jpg",(long)i];
      UIImage *image=[UIImage imageNamed:imageName];
      book.ConverPicture=image;
      book.BookName=[NSString stringWithFormat:@"百年孤独%ld",(long)i];
      book.Author=[NSString stringWithFormat:@"加西亚.马尔克斯%ld",(long)i];
      book.Price=[[NSNumber alloc] initWithInteger:45];
      [self.bookList addObject:book];
   
  }
  if ([NSKeyedArchiver archiveRootObject:self.bookList toFile:_storageListPath]) {
      NSLog(@"数据存档成功");
  }

 多个解档:

1
2
3
4
self.bookList=[NSKeyedUnarchiver unarchiveObjectWithFile:_storageListPath];
Book *nextBook=self.bookList[1];
self.myImageView.image=nextBook.ConverPicture;
NSLog(@"解档成功");

 通过代码基本上发现其实存档和解压是非常简单的一个事情,不过事实这种方式缺点还是很明显的,以这种方式保存数据只能一次性归档保存以及一次性解压。数据较少的时候如果使用感觉比较方便,数据量过多的时候如果想修改其中的某一条,解压整个数据然后归档整个数据还是比较耗时的。最终演示效果如下:

参考资料:https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Archiving/Articles/creating.html#//apple_ref/doc/uid/20000949-BABGBHCA

作者:FlyElephant
出处:http://www.cnblogs.com/xiaofeixiang
说明:博客经个人辛苦努力所得,如有转载会特别申明,博客不求技惊四座,但求与有缘人分享个人学习知识,生活学习提高之用,博客所有权归本人和博客园所有,如有转载请在显著位置给出博文链接和作者姓名,否则本人将付诸法律。

iOS开发-数据存储NSCoder的更多相关文章

  1. IOS开发数据存储篇—IOS中的几种数据存储方式

    IOS开发数据存储篇—IOS中的几种数据存储方式 发表于2016/4/5 21:02:09  421人阅读 分类: 数据存储 在项目开发当中,我们经常会对一些数据进行本地缓存处理.离线缓存的数据一般都 ...

  2. iOS开发UI篇—ios应用数据存储方式(归档)

    iOS开发UI篇—ios应用数据存储方式(归档)  一.简单说明 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦: 偏好设置(将所有的东西都保存在同 ...

  3. iOS开发UI篇—ios应用数据存储方式(归档) :转发

    本文转发至:文顶顶http://www.cnblogs.com/wendingding/p/3775293.html iOS开发UI篇—ios应用数据存储方式(归档)  一.简单说明 在使用plist ...

  4. iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist)

    iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist) 一.ios应用常用的数据存储方式 1.plist(XML属性列表归档) 2.偏好设置 3.NSKeydeArchiver归档(存 ...

  5. iOS开发UI篇—ios应用数据存储方式(偏好设置)

    iOS开发UI篇—ios应用数据存储方式(偏好设置) 一.简单介绍 很多iOS应用都支持偏好设置,比如保存用户名.密码.字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能 每个应用 ...

  6. iOS开发技术分享(1)— iOS本地数据存储

    iOS开发技术分享(1)— iOS本地数据存储 前言: 我本是一名asp.net程序员,后来加入了iOS游戏开发队伍,到现在也有一年多的时间了.这一年来,每天都干到2.3点钟才睡觉,不为别的,只为了学 ...

  7. iOS本地数据存储(转载)

    看到一篇不错的文章,推荐给大家!!! 应用沙盒 1)每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应用必须待在自己的沙盒里,其他应用不能访问该沙盒 2)应用沙盒的文 ...

  8. iOS应用数据存储的常用方式

    iOS应用 数据存储的常用方式 XML属性列表 plist Preference 偏好设置 NSKeyedArchiver 归档 Core Data SQLite3 应用沙盒: Layer:     ...

  9. iOS开发 数据缓存-数据库

    iOS中数据存储方式 Plist(NSArray\NSDictionary) Preference(偏好设置\NSUserDefaults) NSCoding (NSKeyedArchiver\NSk ...

随机推荐

  1. maven pom文件详解

    http://www.blogjava.net/hellxoul/archive/2013/05/16/399345.html http://blog.csdn.net/houpengfei111/a ...

  2. (第3篇)HDFS是什么?HDFS适合做什么?我们应该怎样操作HDFS系统?

    摘要: 这篇文章会详细介绍HDFS是什么,HDFS的作用,适合和不适合的场景,我们该如何操作HDFS?   HDFS文件系统 Hadoop 附带了一个名为 HDFS(Hadoop分布式文件系统)的分布 ...

  3. 6 Django系列之关于models的sql语句日常用法总结

    preface Django提供了强大的ORM,我们可以通过ORM快速的写出我们想要对数据做什么样操作的代码.下面就说说我在日常工作中的用法: 外键关联精确查询 应用场景:表A host字段关联到了表 ...

  4. 超强OCR文字识别软件首选ABBYY FineReader

    提到纸质文档—转换—文本格式—可编辑这些字眼,相信大家的第一反映都是OCR文字识别软件,如何排除错误或利用辅助信息提高识别正确率,是OCR最重要的课题,衡量一个OCR系统性能好坏的主要指标无非是精确度 ...

  5. 数据库事务MTDC出错解决办法

    Communication with the underlying transaction manager has failed 与基础事务管理器的通信失败 排除步驟: 1.檢查MS DTC 設置.[ ...

  6. mysql中查看某个日期是星期几?如何知道某个日期是星期几?某个日期是周几?

    需求描述: mysql中,如果要查看某个日期是星期几,可以用date_format函数实现,在此记录下. 操作过程: 1.通过date_format函数查看某个日期是星期几 mysql> sel ...

  7. flume使用之exec source收集各端数据汇总到另外一台服务器

    转载:http://blog.csdn.net/liuxiao723846/article/details/78133375 一.场景一描述: 线上api接口服务通过log4j往本地磁盘上打印日志,在 ...

  8. ASP.NET 动态创建文本框 TextBox (add TextBox to page dynamically)

    下面的函数每执行一次就生成一个TextBox(其实是<input type="Text">)    var i=0;     function changeIt()   ...

  9. (翻译)2016美国数学建模MCM F题(政策)翻译:难民移民政策建模

    PROBLEM F:Modeling Refugee Immigration Policies With hundreds of thousands of refugees moving across ...

  10. CentOS 6.3下搭建Web服务器

    准备前的工作: 1.修改selinux配置文件(/etc/sysconfig/selinux) 关闭防火墙 (1)把SELINUX=enforcing注释掉 (2)并添加SELINUX=disable ...