(四十一)数据持久化的NSCoding实现 -实现普通对象的存取

NSCoding可以用与存取一般的类对象,需要类成为NSCoding的代理,并且实现编码和解码方法。

假设类Person有name和age两个属性,应该这样设置类:

.h文件:

#import <Foundation/Foundation.h>

@interface Person : NSObject <NSCoding> // 注意要成为代理

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

@end

.m文件

#import "Person.h"

@implementation Person

/**
 *  将对象归档的时候调用
 *
 *  @param aCoder 编码对象
 */

-(void)encodeWithCoder:(NSCoder *)aCoder{
    
    //编码成员变量并存入相应的key
    [aCoder encodeObject:_name forKey:@"name"];
    [aCoder encodeInt:_age forKey:@"age"];
    
}

/**
 *  将对象从文件中读取的时候调用
 *
 *  @param aDecoder 解码对象
 *
 *  @return 读取到的对象
 */
- (id)initWithCoder:(NSCoder *)aDecoder{
    
    if (self = [super init]) {
        
        self.name = [aDecoder decodeObjectForKey:@"name"];
        self.age  = [aDecoder decodeIntForKey:@"age"];
        
    }
    
    return self;
    
}

@end


存储Person的方法:

    Person *p = [[Person alloc] init];
    p.name = @"jack";
    p.age = 15;
    
    NSString *homePath = NSHomeDirectory();
    NSString *docPath = [homePath stringByAppendingPathComponent:@"Documents"];
    NSString *filePath = [docPath stringByAppendingPathComponent:@"test.data"];
    //归档
    [NSKeyedArchiver archiveRootObject:p toFile:filePath];

读取Person的方法:

    NSString *homePath = NSHomeDirectory();
    NSString *docPath = [homePath stringByAppendingPathComponent:@"Documents"];
    NSString *filePath = [docPath stringByAppendingPathComponent:@"test.data"];
    
    //读档(反归档)
    Person *p = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];

一个细节:

假如有一个Student类继承子Person要存储,如果直接存储,只能调用父类的编码方法,因此子类的特有数据不能保存,应该再重新实现归档函数,但是直接调用父类的归档函数即可初始化原来的数据,再初始化自己的即可。

Tip:通过super调用父类方法可以省去原来属性的初始化。

假设Student多一个学号属性no:

@interface Student : Person

@property (nonatomic, assign) int no;

@end
#import "Student.h"

@implementation Student

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

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

@end




原文地址:https://www.cnblogs.com/aiwz/p/6154210.html