免费开源的iOS开发学习平台

归档:5-子类对象的归档

在我们创建数据模型过程中,经常会涉及到子类的创建,如果子类对象需要执行归档操作,那么我们还需要做一些特殊的设置。

子类对象归档说明

当我们需要对子类对象进行归档时,在创建该子类时同样需要遵守NSCoding协议,并且实现归档/解档方法。在实现归档/解档的方法中,我们需要先调用父类的归档/解档方法,然后再对子类中定义的属性执行归档/解档操作。

示例代码

下方的示例代码中,创建了一个Student类,其是Person类的子类,我们针对Student类实现针对该类的归档与解档方法。

  • 新增一个Student类,该类继承自Person类,并且有一个score属性。同时,Student类遵守NSCoding协议。

#import "Person.h"
@interface Student : Person <NSCoding>
@property (nonatomic, strong) NSString *score;
@end
  • 在Student.m文件中,实现归档/解档方法,注意,需要提前调用父类的归档/解档方法
-(void)encodeWithCoder:(NSCoder *)aCoder{
    //调用父类的方法
    [super encodeWithCoder:aCoder];
    [aCoder encodeObject:self.score forKey:@"score"];
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
    //调用父类的方法
    self = [super initWithCoder:coder];
    if (self) {
        self.score = [coder decodeObjectForKey:@"score"];
    }
    return self;
}
  • 在ArchiveService工具类中添加如下两个用于子类读写的方法,并实现其功能
+ (BOOL) writeSubObjectToArchiveFile:(Student *) object{
    //获取文件路径
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *filePath = [docPath stringByAppendingPathComponent:@"student.archive"];
    //调用NSKeyedArchiver的类方法archiveRootObject:toFile:将对象归档(返回一个布尔值)
    return  [NSKeyedArchiver archiveRootObject:object toFile:filePath];
}
+ (Student *) readSubObjectFromArchiveFile{
    //获取文件路径
    NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    NSString *filePath = [docPath stringByAppendingPathComponent:@"student.archive"];
    //调用NSKeyedUnarchiver的类方法unarchiveObjectWithFile:将文件解档
    Student *student = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
    return student;
}
  • 使用Storyboard搭建如下的界面,在上一节创建的界面基础上,再添加一个UITextField控件,用于获取用户输入的score值

  • 在控制器类中实现【写入归档文件】、【读取归档文件】按钮点击功能
- (IBAction)writeToFile:(id)sender {
    Student *student = [[Student alloc] init];
    student.name = self.nameTextField.text;
    NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
    student.age = [formatter numberFromString:self.ageTextField.text];
    student.score = self.scoreTextField.text;
    if([ArchiveService writeSubObjectToArchiveFile:student]){
        NSLog(@"归档成功");
    };
}
- (IBAction)readFromFile:(id)sender {
    Student *student = [ArchiveService readSubObjectFromArchiveFile];
    NSLog(@"student name: %@, student age:%@, student score:%@", student.name,student.age,student.score);
}
  • 运行程序,输入score对应的值

  • 点击【写入归档文件】后,控制台显示“归档成功”,在沙盒中新增student.archive文件

  • 点击【读取归档文件】,可以从student.archive文件中读取存储的对象,并打印出对象各个属性值

https://github.com/99ios/13.4.5