Archiving Objective-C Objects with NSCoding

For the seasoned Cocoa developer, this is a piece of cake. For newer developers, this can be a real pain, especially if you don’t know what you’re looking for. I get this question a decent amount, so I figured I’d put a quick guide together.

The Problem

You can’t put just any object in a plist. This mainly gets people when they want to put something into NSUserDefaults and get an error (because NSUserDefaults archives to a plist under the hood).

Plists only support the core types: NSString, NSNumber, NSDate, NSData, NSArray, NSDictionary (and their CF buddies thanks to the toll-free bridge). The key here is NSData. You can convert any object to NSData with the NSCoding protocol.

The Solution

There are two things you have to do: implement NSCoding and then use the archiver and unarchiver.

Implementing NSCoding

Say you have an object that looks like this:

@interface Note : NSObject {
NSString *title;
NSString *author;
BOOL published;
} @property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *author;
@property (nonatomic) BOOL published; @end
#import "Note.h"

@implementation Note

@synthesize title;
@synthesize author;
@synthesize published; - (void)dealloc {
[title release];
[author release];
[super dealloc];
} @end

Pretty simple, right?

Now, all you have to do to implement NSCoding is the following:

@interface Note : NSObject <NSCoding> {
NSString *title;
NSString *author;
BOOL published;
} @property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *author;
@property (nonatomic) BOOL published; @end
#import "Note.h"

@implementation Note

@synthesize title;
@synthesize author;
@synthesize published; - (void)dealloc {
[title release];
[author release];
[super dealloc];
} - (id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
self.title = [decoder decodeObjectForKey:@"title"];
self.author = [decoder decodeObjectForKey:@"author"];
self.published = [decoder decodeBoolForKey:@"published"];
}
return self;
} - (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:title forKey:@"title"];
[encoder encodeObject:author forKey:@"author"];
[encoder encodeBool:published forKey:@"published"];
} @end

Pretty simple. All I did was add the <NSCoding> protocol delectation in the header file and initWithCoder: and encodeWithCoder: in the implementation. You use these methods to tell NSCoder how to encode your object into data. Notice how two of the variables are objects and one was a BOOL. You have to use different methods for non-objects. The NSCoder documentation has the full list.

Remember, that you can use NSCoder to archive your object however whatever you want. It doesn’t have to just be all of the instance variables in your object, although that’s what you’ll do 90% of the time.

Using the Archiver and Unarchiver

This part is also really easy. Let’s say you have an array of notes that you want to put into NSUserDefaults, here’s the code:

// Given `notes` contains an array of Note objects
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:notes];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"notes"];

Unarchiving is just as easy:

NSData *notesData = [[NSUserDefaults standardUserDefaults] objectForKey:@"notes"];
NSArray *notes = [NSKeyedUnarchiver unarchiveObjectWithData:notesData];

用NSCoding协议完成“编码/解码”操作-Object-C的更多相关文章

  1. java中文乱码解决之道(五)-----java是如何编码解码的

    在上篇博客中LZ阐述了java各个渠道转码的过程,阐述了java在运行过程中那些步骤在进行转码,在这些转码过程中如果一处出现问题就很有可能会产生乱码!下面LZ就讲述java在转码过程中是如何来进行编码 ...

  2. java中文乱码解决之道(六)-----javaWeb中的编码解码

    在上篇博客中LZ介绍了前面两种场景(IO.内存)中的java编码解码操作,其实在这两种场景中我们只需要在编码解码过程中设置正确的编码解码方式一般而言是不会出现乱码的.对于我们从事java开发的人而言, ...

  3. java中文乱码解决之道(六)—–javaWeb中的编码解码

    在上篇博客中LZ介绍了前面两种场景(IO.内存)中的java编码解码操作,其实在这两种场景中我们只需要在编码解码过程中设置正确的编码解码方式一般而言是不会出现乱码的.对于我们从事java开发的人而言, ...

  4. java中文乱码解决之道(五)—–java是如何编码解码的

    原文出处:http://cmsblogs.com/?p=1491 在上篇博客中LZ阐述了java各个渠道转码的过程,阐述了java在运行过程中那些步骤在进行转码,在这些转码过程中如果一处出现问题就很有 ...

  5. java是如何编码解码的

    在上篇博客中LZ阐述了java各个渠道转码的过程,阐述了java在运行过程中那些步骤在进行转码,在这些转码过程中如果一处出现问题就很有可能会产生乱码!下面LZ就讲述java在转码过程中是如何来进行编码 ...

  6. url参数的编码解码Demo

    为了保证在页面传递数据的安全性,我们通常会对Url传递的参数进行编码解码操作.我们写一个Demo剖析URL编码解码过程. 完整Demo下载地址 1. Url参数如何在服务端进行编码和解码. 1.1 U ...

  7. 第57节:Java中流的操作以及编码解码

    我的博客: https://huangguangda.cn/ https://huangguangda.github.io/ 前言: 编码解码:编码时将信息从一种形式变成为另一种形式,成为编码.编码为 ...

  8. day8_文件操作及编码解码

    一.文件操作基本流程 计算机系统分为:计算机硬件,操作系统,应用程序三部分. 我们用python或其他语言编写的应用程序若想要把数据永久保存下来,必须要保存于硬盘中,这就涉及到应用程序要操作硬件,众所 ...

  9. python基础3之文件操作、字符编码解码、函数介绍

    内容概要: 一.文件操作 二.字符编码解码 三.函数介绍 一.文件操作 文件操作流程: 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 基本操作: #/usr/bin/env ...

随机推荐

  1. ThinkPHP3.2.3中,查询语句中in的使用方法。

    //删除分类 public function del(){ $cid = I('get.cid'); $cate = M('category')->field('cid,pid')->se ...

  2. PHP实用小程序(四)

    <HTML> <HEAD> <TITLE>访问文件时间属性</TITLE> </HEAD> <BODY> <? $Last ...

  3. [ACM] hdu 1285 确定比赛名次 (拓扑排序)

    确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  4. 读取MySQL数据表字段信息

    TP5句式 $fieldinfo = Db::query('SHOW FULL COLUMNS FROM '.$table);//查出数据表所有字段信息Field 字段Comment 字段注释

  5. Node.js 使用Stream的pipe(管道)方法实现文件复制

    Stream模块有一个pipe方法,可以将两个流串起来,实现所有的数据自动从Readable流进入Writable流 "use strict"; const fs = requir ...

  6. linux命令行挂载NTFS文件系统的移动硬盘

    环境 ubuntu 12.04 桌面版 由于我的ubuntu 是安装在vmware 上,如果接入移动硬盘后,它没有办法自动识别ntfs 格式的文件系统,导致mount 盘失败 从网上找到一个方法 首先 ...

  7. 解决IIS中运行TopJUI左侧菜单不显示的问题

    TopJUI演示系统中,模拟数据保存在.json文件中,目前发现有部分用户的IIS容器默认情况下是不支持.json文件的请求的,因此需要配置一下,可参考下文配置解决: 一.IIS 6 1. MIME设 ...

  8. python之文件路径截取 & endswith()

    文件路径截取: >>> import os >>> path = '/etc/singfor/passwd/sunny/test.log' >>> ...

  9. jave 计算音视频时长

    File source = new File("视频.mp4"); Encoder encoder = new Encoder(); try { MultimediaInfo in ...

  10. Zynq7000开发系列-3(Xilinx交叉编译环境搭建)

    一.前言 上一篇文章说了,在开发之前必须先搭建起交叉编译环境,于是这里我们就介绍一下环境的搭建过程. 其实在所安装的Vivado HLx 2016.4中就包含了Xilinx SDK,在该SDK上即可开 ...