IOS-Archiver文件归档

Posted Brenda

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IOS-Archiver文件归档相关的知识,希望对你有一定的参考价值。

Archiver是持久化数据的一种方式,他跟 Plist的差别在于他能持久化自己定义对象。但他没Plist那么方便。

Archiver默认能持久化的数据有NSNumber,NSArray,NSDictionary,NSString,NSData,由于这几个对象已经实现了

<NSCoding>协议。如果我们要实现一个对象的Archiver持久化 ,也必须实现该对象。


1.<NSCoding>协议主要为归档/恢复文件两个方法

//恢复归档文件为对象
-(id)initWithCoder:(NSCoder *)aDecoder
//归档,使对象持久化
-(void)encodeWithCoder:(NSCoder *)aCoder


----------------

例如以下 。我们首先获取归档文件的路径

#pragma mark 获取文件路径
- (NSString *) filePath
{
    NSArray *dirPaths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSAllDomainsMask, YES);
    NSString *dirPath=dirPaths[0];
    NSString *filePath=[dirPath stringByAppendingPathComponent:@"aa.archiver"];
    return filePath;
}


2.系统默认对象怎样归档(NSNumber,NSArray,NSDictionary,NSString,NSData)

#pragma mark 归档/恢复 Array对象
- (void) savearray
{
    
    NSString *filePath=[self filePath];
//
//    NSArray *[email protected][@"ttt",@"BBB",@25];
//    [NSKeyedArchiver archiveRootObject:arr toFile:filePath];
//
    NSArray *arr1=[NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    NSLog(@"%@",arr1);
}

#pragma mark 归档/恢复 Dictionary对象
- (void) saveDic
{
    NSString *filePath=[self filePath];
//    NSDictionary *[email protected]{@"name":@"lean",@"age":@25};
//    BOOL flag=[NSKeyedArchiver archiveRootObject:dict toFile:filePath];
//    NSLog(@"%d",flag);
    NSDictionary *dict2=[NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    NSLog(@"%@",dict2);
}

3.怎样归档自己定义对象。

定义了一个Person类。例如以下:

#import <Foundation/Foundation.h>

@interface Person : NSObject <NSCoding>

@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) int age;

+ (Person *) initWithName:(NSString *)name andAge:(int) age;

@end

#import "Person.h"

@implementation Person

+ (Person *) initWithName:(NSString *)name andAge:(int) age
{
    Person *p=[[Person alloc] init];
    p.name=name;
    p.age=age;
    return p;
}

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

-(id)initWithCoder:(NSCoder *)aDecoder
{
    [self setName:[aDecoder decodeObjectForKey:@"name"]];
    [self setAge:[aDecoder decodeIntForKey:@"age"]];
    return self;
}

@end
TIP: 无论是encode还是decode 都是依据对象的类型去选用不同的方法。如

encodeInt:forkey:      encodeDouble:forkey:   encodeFloat:forkey: 

decodeObjectForKey:  decodeIntForKey:  decodeDoubleForKey:


NSKeyedArchiver archiveRootObject:toFile:

NSKeyedUnarchiver unarchiveObjectWithFile:  

各自是对须要归档。

恢复的对象进行操作的两个类


定义完了Person类后,在须要归档的地方调用例如以下:

#pragma mark 归档/恢复 自己定义对象
- (void) savePerson
{
    NSString *filePath=[self filePath];
    Person *p=[Person initWithName:@"lean" andAge:22];
    BOOL flag=[NSKeyedArchiver archiveRootObject:p toFile:filePath];
    Person *p2=[NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    NSLog(@"%d-%d",flag,p2.age);
}

对于其Person类,如果该类中还有自己定义对象作为属性。相同实现<NSCoding>协议


4.如果该对象是某个对象子类,这里我们建立一个叫Student类作为Person的子类


#import "Person.h"

@interface Student : Person

@property (nonatomic ,assign) int no;

+ (Student *) initWithName:(NSString *)name andAge:(int) age andNO:(int) no;

@end

相同Student也须要实现NSCoding协议的方法

-(id)initWithCoder:(NSCoder *)aDecoder
{
    if (self=[super initWithCoder:aDecoder]) {
        [self setNo:[aDecoder decodeIntForKey:@"no"]];
    }
    return self;
}

-(void)encodeWithCoder:(NSCoder *)aCoder
{
    [super encodeWithCoder:aCoder];
    [aCoder encodeInt:self.no forKey:@"no"];
}

#pragma mark 归档/恢复 自己定义子类对象
- (void) saveStudent
{
    NSString *filePath=[self filePath];
    Student *p=[Student initWithName:@"lean" andAge:22 andNO:150133];
    BOOL flag=[NSKeyedArchiver archiveRootObject:p toFile:filePath];
    Student *p2=[NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    NSLog(@"%d-%@",flag,p2.name);
}




以上是关于IOS-Archiver文件归档的主要内容,如果未能解决你的问题,请参考以下文章

3dmax在归档时出现归档失败是啥原因造成的?

移动非归档文件并将它们的属性设置为归档在目标目录中

关于 iOS 代码签名策略 - 当我们在没有代码签名的情况下归档项目并稍后使用配置文件将其导出时会发生啥?

分析与归档 - 不同的代码签名要求?

VSCode自定义代码片段——.vue文件的模板

使用 Ansible 归档单个文件夹下的多个文件夹