IOS-Archiver文件归档(2)

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 *arr=@[@"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 *dict=@{@"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文件归档(2),,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。