<pre name="code" class="objc"><span style="font-size:24px;">1 创建一个 JJModel类继承自NSObject</span>
// 1 创建一个 JJModel类继承自NSObject
#import <Foundation/Foundation.h>
@interface JJModel : NSObject<NSCoding>
/**
* 复杂对象进行持久化 需要遵守一个协议 <NSCoding>
*/
@property (nonatomic, retain) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, retain) NSData *data; // 二进制数据
@end
// 2 在 JJModel的.m中
//
// JJModel.m
// LessonNSFileManger
#import "JJModel.h"
@implementation JJModel
- (void)dealloc
{
[_name release];
[_data release];
[super dealloc];
}
#pragma mark - 对复杂对象进行持久化, 叫做归档 与 反归档 (编码与解码)
// 实现NSCoding协议中的两个方法
// 归档方法, 就是编码成就可以持久化的格式 (对属性编码)
- (void)encodeWithCoder:(NSCoder *)aCoder
{
// 每一个属性都要进行重新编码
// 注意: 属性类型
[aCoder encodeObject:self.name forKey:@"name"];
// 除了了对象类型 其他类型都有特殊的编码格式 !!!!!!!!!!!!!!!!!!!!
[aCoder encodeInteger:self.age forKey:@"age"];
[aCoder encodeObject:self.data forKey:@"data"];
}
// 反归档方法 (解码的过程), 就相当于取出来的过程
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
// 解码的过程
// 跟编码一样, 除了对象类型意外, 也有特殊的解码方法
// 注意:: 编码的时候 你给的key 要和解码的key一样
self.name = [aDecoder decodeObjectForKey:@"name"];
// 注意普通数据类型 decodeIntegerForKey
self.age = [aDecoder decodeIntegerForKey:@"age"];
self.data = [aDecoder decodeObjectForKey:@"data"];
}
return self;
}
@end
在controller中
//
// RootViewController.m
// LessonNSFileManger
//
#import "RootViewController.h"
#import "JJModel.h"
#define kDocumentPath [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]
#define kCachesPath [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] // cache文件夹
@interface RootViewController ()
@end
@implementation RootViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self archiver];
[self unArchiver];
}
#pragma mark - 复杂对象的归档 (把model归档为二进制) 实际上归档就相当于把编码完的对象保存data中
- (void)archiver
{
// 初始化对象
JJModel *model = [[JJModel alloc] init];
// 赋值
model.name = @"zhangsan";
model.age = 19;
// 搞一个图片()
// 把一个png格式的图片转化为data类型
// UIImagePNGRepresentation(<#UIImage *image#>) 是一个函数
model.data = UIImagePNGRepresentation([UIImage imageNamed:@"11"]);
// 创建一个可变data 初始化归档对象
NSMutableData *data = [NSMutableData data];
// 创建一个归档对象
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
// 进行归档编码
[archiver encodeObject:model forKey:@"JJModel"];
// 编码完成
[archiver finishEncoding];
// 实际上归档就相当于把编码完的对象保存data中
//NSLog(@"data = %@", data);
// 把存有复杂对象data写入文件中 进行持久化
// 1. 找路径
NSString *dataPath = [kDocumentPath stringByAppendingPathComponent:@"JJModel.da"];
// 2. 调用写入方法
[data writeToFile:dataPath atomically:YES];
[archiver release]; // 释放归档对象
}
#pragma mark - 反归档(解码的过程)
- (void)unArchiver
{
NSString *dataPath = [kDocumentPath stringByAppendingPathComponent:@"JJModel.da"];
// 获取刚才归档的data
NSData *data = [NSData dataWithContentsOfFile:dataPath];
// 创建反归档对象
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
// 解码返回一个对象
// 这个key 移动要跟编码的key一样
JJModel *model = [unarchiver decodeObjectForKey:@"JJModel"];
// 反归档完成
[unarchiver finishDecoding];
[unarchiver release]; // 释放反归档对象
NSLog(@"=== %@", model.name);
UIImage *image = [UIImage imageWithData:model.data];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end