【应用背景】

在数据库中存储数据时,如果对象过于复杂,又不必要创建复杂的表,可以直接把整个对象转化为二进制存入数据库字段,然后取出后再还原即可。

【实现方法】

在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实现任意对象转为二进制的更多相关文章

  1. Java多线程6:Synchronized锁代码块(this和任意对象)

    一.Synchronized(this)锁代码块 用关键字synchronized修饰方法在有些情况下是有弊端的,若是执行该方法所需的时间比较长,线程1执行该方法的时候,线程2就必须等待.这种情况下就 ...

  2. IOS-将任意对象存进数据库

    model // // HMShop.h // 将任意对象存进数据库 // // Created by apple on 14/11/20. // Copyright (c) 2014年 heima. ...

  3. ngx-bootstrap使用03 Alerts组件、利用Object.assign复制对象

    1 Alerts 该组件用于给用户操作提供反馈信息或者提供一些警告信息 2 用法 2.1 下载ngx-bootstrap依赖 参考博文:点击前往 2.2 在模块级别导入AlertModule模块 技巧 ...

  4. WPF利用VisualTreeHelper遍历寻找对象的子级对象或者父级对象

    原文:WPF利用VisualTreeHelper遍历寻找对象的子级对象或者父级对象 简介 本文将完整叙述我利用VisualTreeHelper实现题述功能的全部过程,想直接看函数实现的朋友可以跳到函数 ...

  5. 利用HttpWebRequest实现实体对象的上传

    一 简介 HttpWebRequest和HttpWebResponse类是用于发送和接收HTTP数据的最好选择.它们支持一系列有用的属性.这两个类位 于System.Net命名空间,默认情况下这个类对 ...

  6. Progress.js – 为页面上的任意对象创建进度条效果

    Progress.js 是一个 JavaScript 和 CSS3 的库,它帮助开发人员为网页上的每个对象创建和管理进度条效果.你可以设计自己的模板,进度条或者干脆定制. 您可以使用 Progress ...

  7. jq对象转为dom对象:$(".div1")[0] dom对象转为jq对象:$(dom对象)

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...

  8. Js中找任意对象的原型方法及改造原型

    Java中有运行时类型识别,js可以很方便的模仿这个特性,因为所有js对象都有一个属性constructor(构造器),表示这个对象的构造方法,原型与构造方法同名,所以可以通过这儿知道任意对象的原型名 ...

  9. c# 数据库编程(利用DataSet 和 DataAdaper对象操作数据库--跨表操作)

    上篇文章我们介绍了如何利用DataSet 和 DataAdaper对象来对单张表进行操作. 本文我们将介绍如何进行跨表操作. 我们通过具体例子方式进行演示,例子涉及到三张表. 1)student表(学 ...

随机推荐

  1. [BZOJ]1069 最大土地面积(SCOI2007)

    计算几何经典题,贴板子. Description 在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成的多边形面积最大. Input 第1行一个正整数N,接 ...

  2. 在QEMU中调试ARM程序【转】

    转自:http://linuxeden.com/html/develop/20100820/104409.html 最近我想调试一个运行在QEMU模拟ARM系统中的Linux程序.我碰到过一些麻烦,因 ...

  3. 笔记14 Hello Spring MVC

    搭建一个SpringMVC所需要的包: 1.创建MySpringMVC项目,使用dynamic web project的方式. 2.导入jar包,放到/WebContent(WebRoot)/WEB- ...

  4. OpenCV环境搭建(一)

    此环境搭建是OpenCV的python(一下简称py)开发环境搭建,建立在py3的环境和语法上实现的. windows系统搭建 系统环境:windows 10 + python 3.6 + OpenC ...

  5. 两个App之间调起通信

    前言 经常使用一些app的分享功能,比如点击QQ分享,就从app打开(跳转到)QQ,然后分享完之后又回到我们的app,那么这是怎样实现的呢? 假设有这么一个需求,由app1跳转到app2,当app2完 ...

  6. div英文内容超过div长度

    添加css word-break: normal;word-wrap: break-word;

  7. WPF TextBlock 判断 isTextTrimmed 文本是否超出

    WPF TextBlock 设置TextTrimming情况下 判断 isTextTrimmed(Text 文本是否超出 是否出现了省略号) private bool HasTextTrimmed(T ...

  8. javascript实现图片的预览

    简单javascript代码 实现上传图片预览 <body> <!-- 设置当有图片准备上传时触发javascript代码--> <input type="fi ...

  9. 微信小程序 发现之旅(一)—— 项目搭建与页面跳转

    开发微信小程序需要注册一个小程序账号,具体流程可以参照官方教程: https://mp.weixin.qq.com/debug/wxadoc/dev/index.html 开通账户之后,在 “开发设置 ...

  10. grab window

    #include <Windows.h> #include <iostream> using namespace std; #if 0 int CaptureAnImage(/ ...