对象序列化(对对象的归档NSKeyedArchiver、接档NSKeyedUnarchiver)的理解

之前只是对归档和接档的应用比较的熟练,但是没有接触到对象序列化的说法,今天遇到原来就是对归档和接档的另一个说法

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
对象系列化要点
 
 1.数据模型类的创建,并且在数据模型类中实现<NSCoding>协议
 
//序列化所调用的方法
 
- (void)encodeWithCoder:(NSCoder*)aCoder
 
{
 
NSLog(@"-======------1111");
 
//编码的是该对象的属性
 
    [aCoderencodeObject:self.nameforKey:@"NAME_KEY"];
 
    [aCoderencodeObject:self.numberforKey:@"NUMBER_KEY"];
 
}
 
//反序列化所调用的方法
 
- (id)initWithCoder:(NSCoder*)aDecoder
 
{
 
self= [superinit];
 
if(self) {
 
NSLog(@"-======------2322222233222");
 
//解码的也是对象的属性,按照编码时所指定的key进行解码
 
self.name= [aDecoderdecodeObjectForKey:@"NAME_KEY"];
 
self.number= [aDecoderdecodeObjectForKey:@"NUMBER_KEY"];
 
    }
 
returnself;
 
}
 
//把该对象存储到本地
 
//1.创建的一个可变data,将来存放序列化(编码)的数据的
 
NSMutableData*data = [[NSMutableDataalloc]init];
 
//创建一个序列化的对象,并且告诉这个对象,序列化后的数据所存放的地方
 
NSKeyedArchiver*archiver = [[NSKeyedArchiveralloc]initForWritingWithMutableData:data];
 
//2.开始序列化,并指定一个key
 
    [archiverencodeObject:userforKey:@"USER_KEY"];
 
//3.结束序列化
 
    [archiverfinishEncoding];
 
//4.指定一个存储路径
 
NSString*path = [NSHomeDirectory()stringByAppendingPathComponent:@"Documents/info.plist"];
 
//存储data
 
    [datawriteToFile:pathatomically:YES];
 
//5.解决内存问题
 
    [datarelease];
 
    [archiverrelease];
 
以下为反序列化
 
//1.去存储的序列化数据
 
NSString*path = [NSHomeDirectory()stringByAppendingPathComponent:@"Documents/info.plist"];
 
//判断文件是否存在
 
if([[NSFileManagerdefaultManager]fileExistsAtPath:path]) {
 
//获取路径中的data数据
 
NSData*data = [NSDatadataWithContentsOfFile:path];
 
//2.告诉反序列化对象,需要解码哪些数据
 
NSKeyedUnarchiver*unArchiver = [[NSKeyedUnarchiveralloc]initForReadingWithData:data];
 
//3.根据指定的key取出原来存放的对象
 
ZYUser*user = [unArchiverdecodeObjectForKey:@"USER_KEY"];
 
//Class test =  NSClassFromString(@"ZYUser");
 
//4.结束反序列化
 
        [unArchiverfinishDecoding];
 
//5.解决内存问题
 
        [unArchiverrelease];
 
self.nameTf.text= user.name;
 
self.numberTf.text= user.number;
 
    }   

 

 

 

实例应用代码:

 
//1、设置归档路径,该路径需要详细到文件(不能是文件夹)
//2、得到要归档的对象
//3、通过NSKeyedArchiver调用archiveRootObject方法,进行归档
//4、解档 通过NSKeyedUnarchiver调用unarchiveObjectWithFile进行解档,注意,该方法返回值类型为id
- (void)viewDidLoad {
    [super viewDidLoad];
 
    NSString *path = NSHomeDirectory();
    NSString *documents = [path stringByAppendingPathComponent:@"Documents"];
   
    //字符串的归档、解档
    NSString *strPath = [documents stringByAppendingPathComponent:@"string.txt"];

    NSString *newsStr = @"新闻联播";
   
    [NSKeyedArchiver archiveRootObject:newsStr toFile:strPath];
    NSLog(@"%@",strPath);
   
    NSString *str = [NSKeyedUnarchiver unarchiveObjectWithFile:strPath];
    NSLog(@"--%@",str);
   
    //数组的归档 解档

    NSString *arrPath = [documents stringByAppendingPathComponent:@"arr.123"];
    NSArray *arr = @[@"1",@"2",@"3"];
    [NSKeyedArchiver archiveRootObject:arr toFile:arrPath];
    NSArray *arr2 = [NSKeyedUnarchiver unarchiveObjectWithFile:arrPath];
    NSLog(@"arr2:%@",arr2);
   
    //字典的归档解档
    NSString *dicPath = [documents stringByAppendingPathComponent:@"dic.123"];
    NSDictionary *dictionary = @{@"名字":@"张三",
                                 @"性别":@"男",
                                 @"年领":@"45"};
    [NSKeyedArchiver archiveRootObject:dictionary toFile:dicPath];
    NSDictionary *dictionary1 = [NSKeyedUnarchiver unarchiveObjectWithFile:dicPath];
    NSLog(@"%@",dictionary1);
   
}
 
自定义类的归档(建一个Student类实现NSCoding的协议方法)
 
Student.h文件
#import <Foundation/Foundation.h>
//如果需要对自定义类进行归档,则该类需要遵循NSCoding协议,并且实现其协议方法
@interface Student : NSObject<NSCoding>

@property (nonatomic, copy) NSString *name;
@end
Student.m文件
#import "Student.h"

@implementation Student
//实现encodeWithCoder协议方法,当系统对自定义类的对象进行归档时,会调用此方法,归档其属性
-(void)encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:_name forKey:@"name"];//对属性的归档
}

//实现initWithCoder方法,当系统对自定义类的对象进行解档时,会调用此方法,可以看成是一个初始化的过程,返回一个对象,并且对其属性进行解档
-(id)initWithCoder:(NSCoder *)aDecoder{
    self = [super init];
    if (self) {
        _name = [aDecoder decodeObjectForKey:@"name"];//对属性的解档,注意,此处的key要与归档时使用的key保持一致
    }
    return self;
}
@end
 
 
ViewController.h文件
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@end
 
ViewController.m文件
 
#import "ViewController.h"
#import "Student.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/student.txt"];
    NSLog(@"%@",path);
   
    Student *s = [[Student alloc] init];
    s.name = @"张三";
   
    [NSKeyedArchiver archiveRootObject:s toFile:path]; //归档
   
    Student *s1 = [NSKeyedUnarchiver unarchiveObjectWithFile:path];//解档
    NSLog(@"%@",s1.name);
   
}
 
 
 
 
 
posted @   #零下一度&  阅读(308)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
点击右上角即可分享
微信分享提示