·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> app软件开发 >> IOS开发 >> OC对象的归档及解档浅析

OC对象的归档及解档浅析

作者:佚名      IOS开发编辑:admin      更新时间:2022-07-23

对象归档,就是把内存中对象持久化。

对象解档,就是把持久化的对象读取到内存。

oc中对象归档解档大致分为以下几种方法:

从数量上可以分为:

  1. 对单个对象归档解档
  2. 对多个对象归档解档

从对象的存在形式上可以分为:

  1. 系统对象归档解档
  2. 自定义对象归档解档

接下来逐一编写代码做简单实现

1.单个系统对象归档及解档:

void SingleSystemObject(){
    NSArray *arr = [NSArray arrayWithObjects:@1,@"你好",@3, nil];
    
    NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:@"array.txt"];
    //对象归档
    BOOL success = [NSKeyedArchiver archiveRootObject:arr toFile:filePath];
    if (success) {
        NSLog(@"归档成功");
    }
    
    //对象解档
    NSArray *arr2 = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    
    for (NSString *str in arr2) {
        NSLog(@"%@",str);
    }
}

2. 多个系统对象归档及解档

void MultiSystemObject(){
    NSArray *arr = [NSArray arrayWithObjects:@1,@2,@"中文", nil];
    NSInteger integer = 10;
    BOOL archiverBool = YES;
    
    
    /*------对象归档--------------------*/
    NSMutableData *data = [NSMutableData data];
    
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    
    //对多个对象编码归档,key是解档时对象的标识符,可任意编写
    //encode有多个重载,但并不是任何系统对象都有重载方法
    [archiver encodeObject:arr forKey:@"arr"];
    [archiver encodeInteger:integer forKey:@"integer"];
    [archiver encodeBool:archiverBool forKey:@"archiverBool"];
    //完成编码
    [archiver finishEncoding];
    
    NSString *filepath = [NSHomeDirectory() stringByAppendingPathComponent:@"1.txt"];
    
    //将data以原子操作方式写入文件
    BOOL success = [data writeToFile:filepath atomically:YES];
    
    if (success) {
        NSLog(@"归档成功");
    }
    /*------对象归档--------------------*/
    
    /*------对象解档--------------------*/
    //将文件数据加载入NSData对象
    NSData *data2 = [NSData dataWithContentsOfFile:filepath];
    
    //使用NSData对象初始化接档器
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data2];
    
    //根据归档时的类型和key解档对应数据
    NSArray *arr2 = [unarchiver decodeObjectForKey:@"arr"];
    NSInteger integer2 = [unarchiver decodeIntegerForKey:@"integer"];
    BOOL unarchiveBool = [unarchiver decodeBoolForKey:@"archiveBool"];
    
    NSLog(@"%@",arr2);
    NSLog(@"%ld",integer2);
    NSLog(@"%d",unarchiveBool);
    /*------对象接档--------------------*/
}

3.自定义对象归档及解档

自定义对象实现可归档解档,需遵守NSCoding协议,该协议下有两个方法需要实现,分别是

归档编码

- (void)encodeWithCoder:(NSCoder *)aCoder

归档解码

- (id)initWithCoder:(NSCoder *)aDecoder

此两个方法中实现自定义对象中自定义成员变量归档时的编码和解码方式,类似于多系统对象归档的实现方式,即将成员变量按类型编码并制定key,解码时根据key按类型解码并赋值给成员变量,最终将对象返回。简单代码实现如下:

Person.m

@interface Person : NSObject <NSCoding>
@PRoperty (copy,nonatomic)NSString *name;
@property (assign,nonatomic)NSInteger age;
@end

@implementation Person
- (void)encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:self.name forKey:@"name"];
    [aCoder encodeInteger:self.age forKey:@"age"];
}
- (id)initWithCoder:(NSCoder *)aDecoder{
//    self = [super init];
//    if (self) {
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.age = [aDecoder decodeIntegerForKey:@"age"];
//    }
    return self;
}

- (NSString *)description{
    NSString *desc = [NSString stringWithFormat:@"name = %@,age = %ld",self.name,self.age];
    return desc;
}
@end

 归档解档代码:

void UserDefinedObject(){
    Person *p = [[Person alloc] init];
    p.name = @"yangys";
    p.age = 10;
    
    //归档
    NSString *filepath = [NSHomeDirectory() stringByAppendingPathComponent:@"person.txt"];
    
    BOOL success = [NSKeyedArchiver archiveRootObject:p toFile:filepath];
    
    if (success) {
        NSLog(@"归档成功");
    }
    
    //解档
    Person *person = [NSKeyedUnarchiver unarchiveObjectWithFile:filepath];
    
    
    NSLog(@"%@",person);
}

自定义多个对象的归档及解档如多个系统对象的归档及解档。

这里值得一提的是,系统对象的归档及解档中,只有遵守了NSCoding协议或其子协议的系统对象才可进行归档及解档。