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. Weekly Contest 111-------->942. DI String Match

    Given a string S that only contains "I" (increase) or "D" (decrease), let N = S. ...

  2. CodeForces 600C【构造】

    题意: 在原字符串中修改数量最少,然后保证最小字典序. #include <bits/stdc++.h> using namespace std; typedef long long LL ...

  3. 进击python第二篇:初识

    入门拾遗 模块 模块用以导入python增强其功能扩展 1.使用 import [模块名] 导入,应用方式:模块. 函数,例: >>> import math >>> ...

  4. python 的 数据类型

    数据类型 1.1整型int py2中有int有范围,超出自动转为long长整型,py3中只有int 整除py2中无小数,可加一行代码实现 十进制转二进制 print(bin(10))十进制转八进制 p ...

  5. unicode官网 unicode码表和标准下载

  6. JMeter提取和重用作为变量 - 具有更多提取器

    这是我们最受欢迎的博文,我们添加了更多提取器.这篇文章解释了如何使用正则表达式提取器从第一个请求的响应中提取密钥,并将提取的密钥用于后续请求.我们称之为JMeter Extract并重复使用. 现在您 ...

  7. BZOJ1053(数学结论进行剪枝搜索)

    Description 对于任何正整数x,其约数的个数记作g(x).例如g(1)=1.g(6)=4.如果某个正整数x满足:g(x)>g(i) 0<i<x,则称x为反质数.例如,整数1 ...

  8. centOS+uwsgi+nginx 部署flask项目,问题记录

    用flask做的项目想要部署到centOS系统上,填了一些坑,终于成功了,记录一下遇到的问题: 此次部署主要是按照这个博客进行的 https://www.cnblogs.com/Ray-liang/p ...

  9. MDX之Case When用法

    with member [Measures].[终端销售数量总计] as sum(ytd([日期].[年月].CurrentMember),[Measures].[终端销售数量]) member [M ...

  10. Java动态解析域名

    Java动态解析域名 Java提供InetAddress类,可以对域名-IP进行正向.逆向解析. InetAddress解析的时候一般是调用系统自带的DNS程序. linux 默认的DNS方式是读取/ ...