将数组或者字典对象写入沙盒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];
网友评论