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日

相关文章

  • 基于c语言中调试工具的用法汇总(不包含gdb)

    基于C语言中调试工具的用法汇总 在C语言程序的开发中,我们常常需要使用调试工具来对代码进行调试。本文将会汇总介绍一些常用的调试工具及其用法。 1. 什么是调试? 调试(Debugging)指在软件开发的过程中,从已有代码中逐步排除一个个错误,以达到使程序能够符合预期要求,并达到较高的可靠性与较好的性能优化的过程。调试的过程常常需要使用调试工具。 2. 常用的…

    C 2023年5月23日
    00
  • Lua教程(六):编译执行与错误

    Lua教程(六):编译执行与错误 Lua是一门解释型脚本语言,它的源代码需要经过编译才能在计算机上运行。本篇教程将介绍如何编译和执行Lua代码,以及如何处理代码中的错误。 编译执行Lua代码 Lua交互模式 在安装了Lua解释器后,打开终端或命令行,输入lua命令即可进入Lua交互模式。在交互模式下,可以逐行输入Lua代码并立即执行,也可以使用dofile或…

    C 2023年5月23日
    00
  • C语言不使用strcpy函数如何实现字符串复制功能

    要实现字符串复制功能,可以使用C语言内置的strcpy函数,但如果不使用该函数,也可以通过以下两种方法实现: 方法一:使用循环遍历字符串实现字符串复制 该方法的基本思路是使用循环遍历需要复制的字符串,逐个复制字符并放入新的字符数组中。代码示例如下: // 需要复制的字符串 char str1[] = "hello world"; // 初…

    C 2023年5月23日
    00
  • C++ 中const对象与const成员函数的实例详解

    下面是对 “C++ 中const对象与const成员函数的实例详解” 的详细讲解: 什么是 const 对象? const 对象:指一旦被初始化后就不能被修改的对象。 const 对象必须在创建时进行初始化,因为一旦创建后就不能再改变它的值。 访问一个 const 对象的地址是完全合法的。 普通的 const 对象 看以下代码示例: #include &lt…

    C 2023年5月22日
    00
  • C语言实现全排列算法模板的方法

    C语言实现全排列算法,是一个经典的算法问题,其思路也很简单。下面是实现全排列算法的详细攻略。 问题背景 给定长度为n的数组arr,将arr进行全排列。 也就是说,对于arr中的任意两个元素a和b(a不等于b),排列结果中a和b的相对位置可能不同。 解题思路 我们可以按以下步骤来实现全排列算法。 首先从数组的第一个元素开始,将其与后面的所有元素交换位置 交换后…

    C 2023年5月22日
    00
  • C语言用指针表示法传递一维数组

    下面我将详细讲解C语言中如何用指针表示法传递一维数组。 什么是指针表示法传递一维数组 C语言中,传递一维数组有两种方法:传递数组首地址和传递数组数组名。使用指针表示法传递一维数组可以实现在函数内部对数组元素的访问和修改。 使用指针表示法传递一维数组,实际上是将数组名所代表的地址传递给指针变量,通过指针变量访问数组的各个元素。 如何实现指针表示法传递一维数组 …

    C 2023年5月9日
    00
  • C++全面精通类与对象

    C++全面精通类与对象攻略 什么是类和对象 在C++中,类(class)是一种自定义数据类型,可以用来描述具有相同属性和方法的一组对象。而对象(object)则是类的一个具体实例。 类是一个抽象的概念,它定义了数据类型的属性和方法,包括数据成员和成员函数,但并不占用内存空间。而对象则是类的一个具体实体,它占用实际的内存空间,可以使用类提供的属性和方法进行操作…

    C 2023年5月22日
    00
  • 联想小新Pro 13笔记本怎么样 联想小新Pro 13笔记本拆机+评测

    联想小新Pro 13 笔记本 联想小新Pro 13 笔记本是一款轻薄便携的高性能笔记本电脑,采用了第8代英特尔酷睿i5/i7处理器、全新独立显卡和全高清显示屏等最新的硬件配置,极大地提升了其性能和使用体验。同时,联想小新Pro 13 笔记本还拥有不错的外观设计和使用续航能力,深受广大用户的喜爱。 联想小新Pro 13 笔记本拆机 步骤1 – 拆卸电池 首先关…

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