1.NSData

NSData是Objective-C语言中数据的基本类型,其成分可以理解为字节指针和长度的封装的类,来看看源代码

@interface NSData : NSObject <NSCopying, NSMutableCopying, NSSecureCoding>

@property (readonly) NSUInteger length;
/*
The -bytes method returns a pointer to a contiguous region of memory managed by the receiver.
If the regions of memory represented by the receiver are already contiguous, it does so in O(1) time, otherwise it may take longer
Using -enumerateByteRangesUsingBlock: will be efficient for both contiguous and discontiguous data.
*/
@property (readonly) const void *bytes NS_RETURNS_INNER_POINTER; @end

所谓数据之基本单位,就好比是万物皆为能量,人死后可以转换成能量(序列化),能量也能孕育成人、或转换成其他物质(反序列化)。

对象转NSData这个过程也可以称为序列化,而NSData转对象则为反序列化。

在网络传输、数据存储等地方,NSData是非常常用的。

或者说,任何一门语言里,序列化的数据(类似NSData的数据)都是非常重要的。

2.NSCoding协议

任何对象转NSData,都需要遵循一个协议,就是NSCoding。

@protocol NSCoding

- (void)encodeWithCoder:(NSCoder *)aCoder;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder; // NS_DESIGNATED_INITIALIZER @end

对于系统的Class,都是默认支持NSCoding协议的,但是如果你自定义了一个对象,比如手动去支持它,如下:

实现NSCoding协议:

(1)在.h文件里

#import <Foundation/Foundation.h>

@interface ContactInfo : NSObject<NSCoding>

@property int userid;
@property (copy) NSString *username;
@property (copy) NSString *FriendlyName;
@property (copy) NSString *phoneNum; @end

(2)在.m文件里的implementation添加实现NSCoding协议的方法:

//每个属性变量分别转码
-(void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.FYusername forKey:@"username"];
[aCoder encodeObject:self.FriendlyName forKey:@"FriendlyName"];
[aCoder encodeObject:self.phoneNum forKey:@"phoneNum"]; } //分别把每个属性变量根据关键字进行逆转码,最后返回一个Student类的对象
-(id)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
self.FYusername = [aDecoder decodeObjectForKey:@"username"];
self.FriendlyName= [aDecoder decodeObjectForKey:@"FriendlyName"];
self.phoneNum= [aDecoder decodeObjectForKey:@"phoneNum"];
}
return self;
}

这样就建立了任何对象和NSdata之间的桥梁。

在实现NSCoding协议后,可以通过归档函数来转成NSData:

    NSData *contactsData=[NSKeyedArchiver archivedDataWithRootObject:ContactsArray]; 

其中的NSCoder是一个编码的工具性类,封装了对象序列化和反序列化的函数,所以实际上,我们并没有自己写序列化算法,只是遵循了这个协议让系统去调用罢了。

3.利用NSData进行存储和深拷贝

实现NSCoding的类,并序列化数据,有2个好处:

1.序列化数据可以直接进行存储

2.序列化数据容易进行完全拷贝

1.序列化数据可以直接进行存储

在iOS中,进行存储比较快捷的方式是NSUserDefaults,存储方式如下:

    [[NSUserDefaults standardUserDefaults] setObject:nickName forKey:UserDefault_NickName];
[[NSUserDefaults standardUserDefaults] synchronize];

但它支持的数据类型很有限:

  NSNumber(NSInteger、float、double),NSString,NSData,NSArray,NSDictionary,BOOL.

一般都是些不可变的基本类型,存储其他类型时,如NSMutableArray等类型时,会崩溃的。

那肿么办?

对的,先转NSData.

    NSData *contactsData=[NSKeyedArchiver archivedDataWithRootObject:ContactsArray];
[[NSUserDefaults standardUserDefaults] setObject:contactsData forKey:UserDefault_ContactsArray];
[[NSUserDefaults standardUserDefaults] synchronize];

当然,不能忽略的是,如果是自定义对象,别忘了给他造NSCoding的桥梁。

除了NSUserDefaults,另外存储NSData的方式可以用归档+地址:

    [NSKeyedArchiver archiveRootObject:obj toFile:path];

具体如何实现NSCoding协议,使用NSUserdefaults和NSKeyedArchiver进行存储,参考:

http://www.cnblogs.com/rayshen/p/4910749.html

2.序列化数据容易进行完全拷贝:

难道拷贝对象这么麻烦吗?对的,要完全拷贝一个对象还真不是那么简单。

关于对象的拷贝,将在下一篇博客中阐述,这里简单说下使用NSKeyedArchiver来实现深拷贝:

主要的方法是先将某个对象转NSData,然后NSData转回赋值给新建对象:

NSData *data = [NSKeyedArchiver archivedDataWithRootObject:oldContactsArray];
NSMutableArray *newContactsArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];

Objective-C NSData与实现NSCoding协议进行序列化和反序列化的更多相关文章

  1. 用NSCoding协议完成“编码/解码”操作-Object-C

    Archiving Objective-C Objects with NSCoding For the seasoned Cocoa developer, this is a piece of cak ...

  2. NSData的一些用法

    //NSData遵循NSCopying NSCoding协议,它提供面向对象的数组存储为字节 //适用与读写文件,而读写文件的时候需要一个缓冲区,而NSDate就提供了这么一个缓存区 //定义一个ch ...

  3. 用户自定义协议client/server代码示例

    用户自定义协议client/server代码示例 代码参考链接:https://github.com/sogou/workflow message.h message.cc server.cc cli ...

  4. iOS-CoreData详解与使用

    上面已经说完了SQLite和FMDB以及两者的区别,本篇将讲述iOS中另一个存储方式,CoreData的使用.通读下来大约10分钟,后续还会根据项目中问题,不断更新. 一.预备知识 在了解CoreDa ...

  5. iOS端IM开发从入门到填坑

      让App聊起来 IM开发从入门到填坑Demo IM的实现方式 拿来主义,使用第三方IM服务 IM的第三方服务商国内有很多,底层协议基本上都是基于TCP的,类似有网易云信.环信.融云.极光IM.Le ...

  6. 架构设计:一种远程调用服务的设计构思(zookeeper的一种应用实践)

    在深入学习zookeeper我想先给大家介绍一个和zookeeper相关的应用实例,我把这个实例命名为远程调用服务.通过对这种应用实例的描述,我们会对zookeeper应用场景会有深入的了解. 远程调 ...

  7. 移动端IM开发需要面对的技术问题

    1.前言 这两年多一直从事网易云信 iOS 端 IM SDK的开发,期间不断有兄弟部门的同事和合作伙伴过来问各种技术细节,干脆统一介绍下一个IM APP的方方面面,包括技术选型(包括通讯方式,网络连接 ...

  8. 转: 透过CAT,来看分布式实时监控系统的设计与实现

    评注: 开源的分布式监控系统 转:http://www.infoq.com/cn/articles/distributed-real-time-monitoring-and-control-syste ...

  9. Protobuf学习 - 入门

    古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 -- 苏轼·<晁错论> 从公司的项目源码中看到了这个东西,觉得挺好用的,写篇博客做下小总结.下面的操作以C++为编程语言,protoc的版 ...

随机推荐

  1. codevs1958 刺激

    难度等级:黄金 1958 刺激 题目描述 Description saffah的一个朋友S酷爱滑雪,并且追求刺激(exitement,由于刺激过度导致拼写都缺了个字母),喜欢忽高忽低的感觉.现在S拿到 ...

  2. JAVA JPA - 示例用法

    JPA(Java Persistence API)是JSR(Java Specification Requests)的一部分,定义了一系列对象持久化的标准,目前实现这一规范的产品有Hibernate. ...

  3. 工作随笔——一次简单的Maven加速构建实战

    注意:所有的编译.打包.部署全部是通过Jenkins完成的. 公司内部有一个项目,开始做的时候已经预计到会有很多客服端.所以开发就搞了如下的结构: fft-api # 公用的API,所有的程序都必须使 ...

  4. The specified framework 'Microsoft.NETCore.App', version '1.0.1' was not found 解决办法

    环境:Centos 7 已经下载安装.NET Core 1.1 Microsoft .NET Core Shared Framework Host Version : Build : 928f77c4 ...

  5. GPS围栏两个多边形相交问题的奇葩解法

    前言 GPS测量仪测量的产地面积,然后提交到系统中,系统需要校验这块产地和其他产地是否有重叠,重叠超过10%就要提出警告这块产地已经被XXX登记入库了.GPS测量仪测量出来的数据是连续的经纬度坐标数据 ...

  6. 使用Redis做预定库存缓存功能

    最近在自己的工作中,把其中一个PHP项目的缓存从以前的APC缓存逐渐切换到Redis中,并且根据Redis所支持的数据结构做了库存维护功能.缓存是在业务层做的,准确讲应该是在MVC模型中Model的O ...

  7. 【python游戏编程之旅】第九篇---嗷大喵快跑小游戏开发实例

    本系列博客介绍以python+pygame库进行小游戏的开发.有写的不对之处还望各位海涵. 前几期博客我们一起学习了,pygame中的冲突检测技术以及一些常用的数据结构. 这次我们来一起做一个简单的酷 ...

  8. nginx location语法使用说明

    语法规则: location [=|~|~*|^~] /uri/ { … } = 开头表示精确匹配 ^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可.nginx不对url做编码,因 ...

  9. CentOS6.6搭建LNMP环境

    CentOS6.6搭建LNMP环境 1.设置yum源,本地安装依赖包 1 yum -y install gcc gcc-c++ automake autoconf libtool make 2.下载依 ...

  10. android 入门笔迹(1)

    环境搭建JDK,JRE,Android SDK,ADT,Eclipse,安卓模拟器AVD xml控制UI界面  Java代码控制UI界面  XML与Java混合控制UI界面  UI:userinter ...