-
iOS的几种数据持久化方案
-
plist文件(属性列表)
-
preference(偏好设置)
-
NSKeyedArchiver(归档)
-
SQLite
-
CoreData
-
沙盒目录结构
-
"应用程序包": 这里面存放的是应用程序的源文件,包括资源文件和可执行文件。
-
Documents: 最常用的目录,iTunes同步该应用时会同步此文件夹中的内容,适合存储重要数据。
-
Library/Caches: iTunes不会同步此文件夹,适合存储体积大,不需要备份的非重要数据。
-
Library/Preferences: iTunes同步该应用时会同步此文件夹中的内容,通常保存应用的设置信息。
-
tmp: iTunes不会同步此文件夹,系统可能在应用没运行时就删除该目录下的文件,所以此目录适合保存应用中的一些临时文件,用完就删除。
-
plist文件,plist文件是将某些特定的类,通过XML文件的方式保存在目录中。
-
这里先说说自定义类的归档和解档
NSObject没有遵循<NSCoding>协议,所以想要调用- (instancetype)initWithCoder:(NSCoder *)aDecoder
/- (void)encodeWithCoder:(NSCoder *)aCoder
方法需要让自定义类遵循该协议
如果需要归档的类是某个自定义类的子类时,就需要在归档和解档之前先实现父类的归档和解档方法。即[super encodeWithCoder:aCoder]
和[super initWithCoder:aDecoder]
方法; -
使用
需要把对象归档是调用NSKeyedArchiver的工厂方法 archiveRootObject: toFile: 方法。
需要从文件中解档对象就调用NSKeyedUnarchiver的一个工厂方法 unarchiveObjectWithFile: 即可。 -
代码
#import <Foundation/Foundation.h>
@interface Person : NSObject<NSCoding>
@property (nonatomic, copy) NSString *dream;
@end
#import "Person.h"
@implementation Person
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
NSLog(@"initWithCoder");
_dream = [aDecoder decodeObjectForKey:@"DreamKey"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder{
NSLog(@"encodeWithCoder");
[aCoder encodeObject:_dream forKey:@"DreamKey"];
}
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
}
@end
#import "ViewController.h"
#import "Person.h"
@interface ViewController ()
@property (nonatomic, strong) Person *boy;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Person *p = [[Person alloc] init];
self.boy = p;
UIButton *btn1 = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
[btn1 setBackgroundColor:[UIColor blueColor]];
UIButton *btn2 = [[UIButton alloc] initWithFrame:CGRectMake(275, 0, 100, 100)];
[btn2 setBackgroundColor:[UIColor redColor]];
[self.view addSubview:btn1];
[self.view addSubview:btn2];
[btn1 setTitle:@"归档" forState:UIControlStateNormal];
[btn2 setTitle:@"解档" forState:UIControlStateNormal];
[btn1 addTarget:self action:@selector(clickBtn1) forControlEvents:UIControlEventTouchUpInside];
[btn2 addTarget:self action:@selector(clickBtn2) forControlEvents:UIControlEventTouchUpInside];
}
- (void)clickBtn1{
self.person.dream = @"happy";
NSMutableArray *arr = [NSMutableArray array];
[arr addObject:self.person];
NSString *homePath = NSHomeDirectory();
NSString *path = [homePath stringByAppendingPathComponent:@"Library/Caches/hehe.archive"];
[NSKeyedArchiver archiveRootObject:arr toFile:path];
}
- (void)clickBtn2{
NSString *homePath = NSHomeDirectory();
NSString *path = [homePath stringByAppendingPathComponent:@"Library/Caches/hehe.archive"];
NSArray *arr = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
if (arr.count) {
self.person = arr[0];
NSLog(@"%@", self.person.dream);
}
}
@end
运行结果
归档和解档- 点击解档,啥都没发生,
- 点击归档,打印encodeWithCoder
- 退出App
- 点击解档,打印"initWithCoder" "happy"
网友评论