(一一五)利用NSKeyedArchiver实现任意对象转为二进制
【应用背景】
在数据库中存储数据时,如果对象过于复杂,又不必要创建复杂的表,可以直接把整个对象转化为二进制存入数据库字段,然后取出后再还原即可。
【实现方法】
在PHP中,使用序列化和反序列化可以实现这样的功能。
在OC中,使用NSKeyedArchiver和NSKedUnarchiver可以实现对象转二进制和二进制转对象,要实现转化,必须遵循NSCoding协议,并且实现encodeWithCoder方法用来转化数据为二进制,实现initWithCoder实现二进制数据还原成类对象,OC的常见类,例如数组、字典等已经实现了这些内容,直接转换即可,如果是自己定义的类,需要手动实现。
下面以将自定义的Person类转化为二进制存储,然后再读取出来的过程,来加深对这个功能的理解。
【具体案例】
①定义Peron类,有三个属性,如下,注意要遵循NSCoding协议。
#import <Foundation/Foundation.h> @interface Person : NSObject <NSCoding> @property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, assign) double height; @end
②实现编码和解码的方法,并且重写description方法方便打印类内数据。
注意:encode和decode时要选择合适的数据类型。
#import "Person.h" @implementation Person - (void)encodeWithCoder:(NSCoder *)encoder{ [encoder encodeObject:self.name forKey:@"name"];
[encoder encodeInteger:self.age forKey:@"age"];
[encoder encodeDouble:self.height forKey:@"height"]; } - (id)initWithCoder:(NSCoder *)decoder{ if (self = [super init]) { self.name = [decoder decodeObjectForKey:@"name"];
self.age = [decoder decodeIntegerForKey:@"age"];
self.height = [decoder decodeDoubleForKey:@"height"];
} return self; } - (NSString *)description{ return [NSString stringWithFormat:@"%@ %ld %lf",_name,_age,_height]; } @end
③随机生成一些Person对象,使用NSKeyedArchiver进行二进制转换,然后存入文件,注意到因为对象放到了数组里,因此对象不需要主动转化为二进制,这个过程会自动完成,注意一定要实现上面的decode和encode方法。
NSMutableArray *persons = [NSMutableArray array];
for (int i = 0; i < 100; i++) {
Person *p = [[Person alloc] init];
p.name = [NSString stringWithFormat:@"<%05d>",arc4random_uniform(10000)];
p.age = arc4random_uniform(100);
p.height = 1.5 + arc4random_uniform(60) / 100.0;
[persons addObject:p];
}
[NSKeyedArchiver archiveRootObject:persons toFile:@"/Users/soulghost/Desktop/persons.data"];
④读取文件,使用NSKeydUnarchiver进行还原,在还原数组时,数组内的数据也被自动还原。
NSMutableArray *persons = [NSKeyedUnarchiver unarchiveObjectWithFile:@"/Users/soulghost/Desktop/persons.data"];
NSLog(@"%@",persons);
由于重写了description方法,类的内容会规范的打印如下:
"<07060> 10 1.960000",
"<05393> 35 1.960000",
"<01438> 68 1.920000",
"<00835> 40 1.710000",
"<00035> 14 1.780000",
"<08394> 66 1.910000",
"<00504> 29 1.580000",
"<03072> 4 1.900000",
"<00473> 7 1.800000",
"<04528> 10 1.790000",
"<05930> 3 1.790000",
"<07390> 2 1.590000",
"<00820> 62 1.670000",
...
通过这么一个简单的案例,就能学会任意对象和二进制对转的方法,这个方法能够跨越不同语言间的类定义不同而实现统一的数据存储,能够轻松实现类的数据库存储。
(一一五)利用NSKeyedArchiver实现任意对象转为二进制的更多相关文章
- Java多线程6:Synchronized锁代码块(this和任意对象)
一.Synchronized(this)锁代码块 用关键字synchronized修饰方法在有些情况下是有弊端的,若是执行该方法所需的时间比较长,线程1执行该方法的时候,线程2就必须等待.这种情况下就 ...
- IOS-将任意对象存进数据库
model // // HMShop.h // 将任意对象存进数据库 // // Created by apple on 14/11/20. // Copyright (c) 2014年 heima. ...
- ngx-bootstrap使用03 Alerts组件、利用Object.assign复制对象
1 Alerts 该组件用于给用户操作提供反馈信息或者提供一些警告信息 2 用法 2.1 下载ngx-bootstrap依赖 参考博文:点击前往 2.2 在模块级别导入AlertModule模块 技巧 ...
- WPF利用VisualTreeHelper遍历寻找对象的子级对象或者父级对象
原文:WPF利用VisualTreeHelper遍历寻找对象的子级对象或者父级对象 简介 本文将完整叙述我利用VisualTreeHelper实现题述功能的全部过程,想直接看函数实现的朋友可以跳到函数 ...
- 利用HttpWebRequest实现实体对象的上传
一 简介 HttpWebRequest和HttpWebResponse类是用于发送和接收HTTP数据的最好选择.它们支持一系列有用的属性.这两个类位 于System.Net命名空间,默认情况下这个类对 ...
- Progress.js – 为页面上的任意对象创建进度条效果
Progress.js 是一个 JavaScript 和 CSS3 的库,它帮助开发人员为网页上的每个对象创建和管理进度条效果.你可以设计自己的模板,进度条或者干脆定制. 您可以使用 Progress ...
- jq对象转为dom对象:$(".div1")[0] dom对象转为jq对象:$(dom对象)
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- Js中找任意对象的原型方法及改造原型
Java中有运行时类型识别,js可以很方便的模仿这个特性,因为所有js对象都有一个属性constructor(构造器),表示这个对象的构造方法,原型与构造方法同名,所以可以通过这儿知道任意对象的原型名 ...
- c# 数据库编程(利用DataSet 和 DataAdaper对象操作数据库--跨表操作)
上篇文章我们介绍了如何利用DataSet 和 DataAdaper对象来对单张表进行操作. 本文我们将介绍如何进行跨表操作. 我们通过具体例子方式进行演示,例子涉及到三张表. 1)student表(学 ...
随机推荐
- [BZOJ]1069 最大土地面积(SCOI2007)
计算几何经典题,贴板子. Description 在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大. Input 第1行一个正整数N,接 ...
- 在QEMU中调试ARM程序【转】
转自:http://linuxeden.com/html/develop/20100820/104409.html 最近我想调试一个运行在QEMU模拟ARM系统中的Linux程序.我碰到过一些麻烦,因 ...
- 笔记14 Hello Spring MVC
搭建一个SpringMVC所需要的包: 1.创建MySpringMVC项目,使用dynamic web project的方式. 2.导入jar包,放到/WebContent(WebRoot)/WEB- ...
- OpenCV环境搭建(一)
此环境搭建是OpenCV的python(一下简称py)开发环境搭建,建立在py3的环境和语法上实现的. windows系统搭建 系统环境:windows 10 + python 3.6 + OpenC ...
- 两个App之间调起通信
前言 经常使用一些app的分享功能,比如点击QQ分享,就从app打开(跳转到)QQ,然后分享完之后又回到我们的app,那么这是怎样实现的呢? 假设有这么一个需求,由app1跳转到app2,当app2完 ...
- div英文内容超过div长度
添加css word-break: normal;word-wrap: break-word;
- WPF TextBlock 判断 isTextTrimmed 文本是否超出
WPF TextBlock 设置TextTrimming情况下 判断 isTextTrimmed(Text 文本是否超出 是否出现了省略号) private bool HasTextTrimmed(T ...
- javascript实现图片的预览
简单javascript代码 实现上传图片预览 <body> <!-- 设置当有图片准备上传时触发javascript代码--> <input type="fi ...
- 微信小程序 发现之旅(一)—— 项目搭建与页面跳转
开发微信小程序需要注册一个小程序账号,具体流程可以参照官方教程: https://mp.weixin.qq.com/debug/wxadoc/dev/index.html 开通账户之后,在 “开发设置 ...
- grab window
#include <Windows.h> #include <iostream> using namespace std; #if 0 int CaptureAnImage(/ ...