Objective-C基础 自定义对象归档详解及简单实例

Objective-C基础:自定义对象归档详解及简单实例

1. 什么是归档?

归档是将对象保存到文件中,以便以后可以恢复对象时使用的一种技术。在iOS开发中,归档通常用于将自定义对象保存到本地,如用户数据、游戏进度等。

2. 归档的分类

归档分为两种:文件归档和系统归档。

  • 文件归档:将对象保存到指定的文件中。
  • 系统归档:将对象保存到系统的偏好设置、键值存储、Core Data等系统库中。

这里主要介绍文件归档。

3. 自定义对象的归档

3.1 实现NSCoding协议

首先需要让自定义对象实现NSCoding协议,该协议包含两个方法:

- (void)encodeWithCoder:(NSCoder *)encoder {
    // encode
}

- (instancetype)initWithCoder:(NSCoder *)decoder {
    // decode
}

编码方法(encodeWithCoder)负责将对象的各个属性转换成归档格式,存储到文件中。解码方法(initWithCoder)则可以根据归档格式从文件中恢复之前保存的对象属性。

具体实现示例如下:

@interface Person : NSObject <NSCoding>

@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;

@end

@implementation Person

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.name forKey:@"name"];
    [encoder encodeInteger:self.age forKey:@"age"];
}

- (instancetype)initWithCoder:(NSCoder *)decoder {
    if (self = [super init]) {
        self.name = [decoder decodeObjectForKey:@"name"];
        self.age = [decoder decodeIntegerForKey:@"age"];
    }
    return self;
}

@end

3.2 归档和解档对象

归档对象需要使用NSKeyedArchiver类,解档对象需要使用NSKeyedUnarchiver类。

// 归档对象
Person *p = [[Person alloc] init];
p.name = @"Jack";
p.age = 20;
NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"person.data"];
BOOL success = [NSKeyedArchiver archiveRootObject:p toFile:filePath];

// 解档对象
Person *p1 = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];

3.3 自定义对象嵌套

如果自定义对象中的属性也是自定义对象,则需要对子对象进行归档和解档。

例如,下面是一个包含自定义对象的Person类:

@interface Book : NSObject <NSCoding>

@property (nonatomic, strong) NSString *name;

@end

@implementation Book

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.name forKey:@"name"];
}

- (instancetype)initWithCoder:(NSCoder *)decoder {
    if (self = [super init]) {
        self.name = [decoder decodeObjectForKey:@"name"];
    }
    return self;
}

@end

@interface Person : NSObject <NSCoding>

@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, strong) Book *book;

@end

@implementation Person

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.name forKey:@"name"];
    [encoder encodeInteger:self.age forKey:@"age"];
    [encoder encodeObject:self.book forKey:@"book"];
}

- (instancetype)initWithCoder:(NSCoder *)decoder {
    if (self = [super init]) {
        self.name = [decoder decodeObjectForKey:@"name"];
        self.age = [decoder decodeIntegerForKey:@"age"];
        self.book = [decoder decodeObjectForKey:@"book"];
    }
    return self;
}

@end

在归档和解档对象时,需要对子对象进行归档和解档:

// 归档对象
Person *p = [[Person alloc] init];
p.name = @"Jack";
p.age = 20;
Book *b = [[Book alloc] init];
b.name = @"iOS开发";
p.book = b;
NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"person.data"];
BOOL success = [NSKeyedArchiver archiveRootObject:p toFile:filePath];

// 解档对象
Person *p1 = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];

4. 示例

下面给出一个具体的示例代码。

// 自定义对象
@interface Book : NSObject <NSCoding>

@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger price;

@end

@implementation Book

- (void)encodeWithCoder:(NSCoder *)encoder {
    [encoder encodeObject:self.name forKey:@"name"];
    [encoder encodeInteger:self.price forKey:@"price"];
}

- (instancetype)initWithCoder:(NSCoder *)decoder {
    if (self = [super init]) {
        self.name = [decoder decodeObjectForKey:@"name"];
        self.price = [decoder decodeIntegerForKey:@"price"];
    }
    return self;
}

@end

// 归档和解档对象
- (void)archiveObject {
    // 归档
    Book *book = [[Book alloc] init];
    book.name = @"iOS开发指南";
    book.price = 50;
    NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"book.data"];
    BOOL success = [NSKeyedArchiver archiveRootObject:book toFile:filePath];

    // 解档
    Book *book1 = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    NSLog(@"book.name = %@, book.price = %ld", book1.name, (long)book1.price);
}

5. 总结

  • 归档是将对象保存到文件中,以便以后可以恢复对象时使用的一种技术。
  • 自定义对象需要实现NSCoding协议,包含两个方法:编码方法(encodeWithCoder)和解码方法(initWithCoder)。
  • 归档和解档对象需要使用NSKeyedArchiver和NSKeyedUnarchiver类。
  • 自定义对象嵌套时,需要对子对象进行归档和解档。
  • 在iOS开发中,通常使用文件归档保存数据到本地。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Objective-C基础 自定义对象归档详解及简单实例 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • QT5 Thread线程的具体实现

    下面是关于QT5 Thread线程的具体实现的完整攻略。 1. 基本概念 Qt 中的线程是通过 QThread 类实现的,它提供了多个函数来操作线程,其中比较常用的包括: start() :启动线程并执行 run() 函数; quit() :通知线程退出; wait() :等待线程退出; terminate() :强制终止线程。 为了自定义线程类,我们需要继…

    C 2023年5月22日
    00
  • C++继承详细介绍

    C++继承详细介绍 C++继承是非常重要的面向对象编程(OOP)概念之一,它允许派生类(子类)继承基类(父类)的特性。通过继承,子类能够重复利用基类的属性和方法,并且可以根据需要添加新的属性和方法。接下来我们将详细介绍C++继承的概念及其相关特性。 基本语法 class BaseClass { // 访问说明符 public: int basePublicV…

    C 2023年5月22日
    00
  • JSON在ASP.NET中使用方法

    当我们需要在ASP.NET中使用JSON时,我们通常使用Newtonsoft.Json库来进行JSON的序列化和反序列化。 序列化JSON 我们可以通过以下代码将对象序列化为JSON字符串: using Newtonsoft.Json; // 创建一个对象 var person = new { Name = "张三", Age = 25,…

    C 2023年5月23日
    00
  • c语言连接mysql数据库的实现方法

    下面是详细讲解连接MySQL数据库的实现方法的完整攻略: 1. 安装MySQL C连接库 在连接MySQL数据库时,我们需要使用到MySQL C连接库,因此我们需要先安装该库。在Linux系统中,我们可以使用以下命令来安装: sudo apt install libmysqlclient-dev 在Windows系统中,我们需要从MySQL官网或源码中下载并…

    C 2023年5月23日
    00
  • python 接口返回的json字符串实例

    完整攻略: 在使用Python编写Web接口的时候,常常需要返回数据,而json是最常用的一种数据格式。可以使用Python自带的json包来处理json数据。Python可以将json字符串转换成对象,也可以将对象转换成json格式字符串。 下面简单讲解一下Python中如何处理json数据。 将Python的字典转换成json字符串 使用Python自带…

    C 2023年5月23日
    00
  • java异常(Exception)处理机制详解

    Java异常(Exception)处理机制详解 Java语言允许程序在运行过程中发生异常。当代码出现了问题,如输入值不符合预期、网络连接出现问题等,就会抛出异常。在 Java 中,异常是一个对象,提供了一种处理程序错误或异常情况的机制。 Java异常的分类 Java提供了众多的异常类型来满足不同的需求。Java异常大致分为三类: 受检异常(Checked E…

    C 2023年5月23日
    00
  • C 运算符

    C 运算符是用于执行特定数学或逻辑操作的特殊符号。在程序中,使用这些运算符来计算表达式的值。下面是一些常用的 C 运算符: 算术运算符 加法运算符(+) 减法运算符(-) 乘法运算符(*) 除法运算符(/) 取模运算符(%) 这些算术运算符用于执行基本的数学运算。例如: int a = 10; int b = 20; int c = a + b; print…

    C 2023年5月10日
    00
  • R语言基础统计方法图文实例讲解

    R语言基础统计方法图文实例讲解 本文将为读者讲解使用R语言进行基础的统计分析方法,具体包括了数据的读取、数据展示及探索性数据分析(EDA)、t检验、方差分析及线性回归分析。 1. 数据的读取 在R语言中,我们可以使用以下代码读取csv或Excel文件: # 读取csv文件 data <- read.csv("data.csv", h…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部