美文网首页iOS 技能
iOS开发数据本地化和归档反归档

iOS开发数据本地化和归档反归档

作者: 夜凉听风雨 | 来源:发表于2020-06-02 22:14 被阅读0次

将数组或者字典对象写入沙盒plist文件中。
如果处理的数据较多比较费时,可以使用多线程异步操作。

    // 全局队列,使用子线程,异步操作。
    dispatch_async(dispatch_get_global_queue(0, 0), ^{

        // 沙盒中tmp文件夹目录
        NSString *tmpPath = NSTemporaryDirectory();
        // 拼接存储目的文件目录
        NSString *fileName = [tmpPath stringByAppendingPathComponent:@"123.plist"];

        NSMutableArray *arr = [NSMutableArray array];
        for (int i = 0; i < 1000; i++) {
            [arr addObject:[NSNumber numberWithInt:i]];
        }
        
        NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arr];
        [data writeToFile:fileName atomically:YES];
        NSMutableArray *array = [NSMutableArray arrayWithContentsOfFile:fileName];
     });

归档的对象需要遵循NSCoding协议。

下面自定义一个Person类

Person.h文件

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface Person : NSObject <NSCoding>

@property (nonatomic, copy) NSString * name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, copy) NSString * sex;
@property (nonatomic, assign) BOOL student;
@property (nonatomic, strong) UIImage * avatar;

@end

NS_ASSUME_NONNULL_END

Person.m文件

#import "Person.h"

@implementation Person

- (instancetype)initWithCoder:(NSCoder *)coder {
    if ([super init]) {
        self.sex = [coder decodeObjectForKey:@"sex"];
        self.name = [coder decodeObjectForKey:@"name"];
        self.age = [coder decodeIntegerForKey:@"age"];
        self.student = [coder decodeBoolForKey:@"student"];
        NSData *data = [coder decodeObjectForKey:@"avatar"];
        self.avatar = [UIImage imageWithData:data];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)coder {
    [coder encodeObject:self.sex forKey:@"sex"];
    [coder encodeObject:self.name forKey:@"name"];
    [coder encodeInteger:self.age forKey:@"age"];
    [coder encodeBool:self.student forKey:@"student"];
   // 注意:图片要转为NSData归档
    NSData *data = UIImageJPEGRepresentation(self.avatar, 1.0f);
    [coder encodeObject:data forKey:@"avatar"];
}
                    
@end

调用的地方

NSString *tmpPath = NSTemporaryDirectory();
NSString *fileName = [tmpPath stringByAppendingPathComponent:@"personFile.data"];
Person *p = [[Person alloc] init];
p.name = @"jonas";
p.sex = @"男";
p.age = 10;
p.student = YES;
p.avatar = [UIImage imageNamed:@"avatar.png"];
// 归档
[NSKeyedArchiver archiveRootObject:p toFile:fileName];
// 反归档
Person *p2 = [NSKeyedUnarchiver unarchiveObjectWithFile:fileName];

还可以使用继承的自定义类

下面我们新建一个Student类继承自Person类

Student.h文件

#import "Person.h"

NS_ASSUME_NONNULL_BEGIN

@interface Student : Person <NSCoding>
@property (nonatomic, assign) CGFloat score;
@property (nonatomic, assign) NSInteger level;
@end

Student.m文件

#import "Student.h"

@implementation Student

- (instancetype)initWithCoder:(NSCoder *)coder {
    if ([super init]) {
        self.sex = [coder decodeObjectForKey:@"sex"];
        self.name = [coder decodeObjectForKey:@"name"];
        self.age = [coder decodeIntegerForKey:@"age"];
        self.student = [coder decodeBoolForKey:@"student"];
        NSData *data = [coder decodeObjectForKey:@"avatar"];
        self.avatar = [UIImage imageWithData:data];
        self.level = [coder decodeIntegerForKey:@"level"];
        self.score = [coder decodeFloatForKey:@"score"];
    }
    return self;
}

- (void)encodeWithCoder:(NSCoder *)coder {
    [coder encodeObject:self.sex forKey:@"sex"];
    [coder encodeObject:self.name forKey:@"name"];
    [coder encodeInteger:self.age forKey:@"age"];
    [coder encodeBool:self.student forKey:@"student"];
    NSData *data = UIImageJPEGRepresentation(self.avatar, 1.0f);
    [coder encodeObject:data forKey:@"avatar"];
    [coder encodeInteger:self.level forKey:@"level"];
    [coder encodeFloat:self.score forKey:@"score"];
}

@end

虽然Student继承自Person类,而且Person类已经遵循NSCoding协议且实现了归档反归档方法,但是Student类继承自Person类的name, sex, age, avatar, student这五个属性还是需要再重新实现归档反归档。

归档反归档

    NSString *tmpPath = NSTemporaryDirectory();
    NSString *fileName = [tmpPath stringByAppendingPathComponent:@"personFile.data"];
    Student *s = [[Student alloc] init];
    s.sex = @"男";
    s.name = @"jonas";
    s.age = 10;
    s.student = YES;
    s.avatar = [UIImage imageNamed:@"avatar.png"];
    s.score = 95.5;
    s.level = 5;
    
    // 归档
    [NSKeyedArchiver archiveRootObject:s toFile:fileName];
    // 反归档
    Person *s2 = [NSKeyedUnarchiver unarchiveObjectWithFile:fileName];

多个自定义对象的归档反归档

    Person *p1 = [[Person alloc] init];
    p1.sex = @"男";
    p1.name = @"jonas";
    p1.age = 10;
    p1.student = YES;
    p1.avatar = [UIImage imageNamed:@"avatar1.png"];

    Person *p2 = [[Person alloc] init];
    p2.sex = @"女";
    p2.name = @"marry";
    p2.age = 12;
    p2.student = NO;
    p2.avatar = [UIImage imageNamed:@"avatar2.png"];
    
    NSMutableData *data = [NSMutableData data];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:p1 forKey:@"p1"];
    [archiver encodeObject:p2 forKey:@"p2"];
    [archiver finishEncoding];
    
    NSString *tmpPath = NSTemporaryDirectory();
    NSString *fileName = [tmpPath stringByAppendingPathComponent:@"personFile.data"];
    [data writeToFile:fileName atomically:YES];
    
    NSMutableData *data2 = [[NSMutableData alloc] initWithContentsOfFile:fileName];
    NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data2];
    Person *p3 = [unarchiver decodeObjectForKey:@"p1"];
    Person *p4 = [unarchiver decodeObjectForKey:@"p2"];
    [unarchiver finishDecoding];

相关文章

网友评论

    本文标题:iOS开发数据本地化和归档反归档

    本文链接:https://www.haomeiwen.com/subject/iknpzhtx.html