个人博客地址
给你的Model插上翅膀,自带归档、反归档功能,能够直接写入沙盒,或从沙盒中读取,打印你的Model可以直接看见内部属性。
打造BaseModel
实际开发中无论MVVM、MVC、还是MVP都有Model的存在,一个好的BaseModel可以精简代码,提高效率;来吧,集成本Model 愉快的使用MJExtension,JSONModel吧。
#import <Foundation/Foundation.h>
@interface BaseModel : NSObject <NSCoding>
@end
#import "BaseModel.h"
#import <objc/runtime.h> //导入Runtime
@implementation BaseModel
#pragma mark - 解档方法
- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
self = [super init];
if (self) {
NSArray * porpertyArray = [self getAllPropertys];
for (NSString *string in porpertyArray) {
NSString *key = [string substringFromIndex:1];
[self setValue:[aDecoder decodeObjectForKey:[NSString stringWithFormat:@"%@",key]] forKey:key];
}
}
return self;
}
#pragma mark - 归档方法
- (void)encodeWithCoder:(NSCoder *)aCoder
{
//获取所有属性
NSArray * porpertyArray = [self getAllPropertys];
for (NSString * name in porpertyArray) {
//去掉属性名前面的_
NSString * key = [name substringFromIndex:1];
//约定好的键值对 c+key
[aCoder encodeObject:[self valueForKey:key] forKey:[NSString stringWithFormat:@"%@",key]];
}
}
#pragma mark - 获取model的所有属性
-(NSArray *)getAllPropertys{
NSMutableArray * array = [[NSMutableArray alloc]init];
unsigned int * count = malloc(sizeof(unsigned int));
//调用runtime的方法
//Ivar:方法返回的对象内容对象,这里将返回一个Ivar类型的指针
//class_copyIvarList方法可以捕获到类的所有变量,将变量的数量存在一个unsigned int的指针中
Ivar * mem = class_copyIvarList([self class], count);
//进行遍历
for (int i=0; i< *count ; i++) {
//通过移动指针进行遍历
Ivar var = * (mem+i);
//获取变量的名称
const char * name = ivar_getName(var);
NSString * str = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
[array addObject:str];
}
//释放内存
free(count);
//注意处理野指针
count=nil;
return array;
}
#pragma mark - description
- (NSString *)description
{
NSString *keyValue = @"\n";
NSArray * porpertyArray = [self getAllPropertys];
for (NSString *string in porpertyArray) {
NSString *key = [string substringFromIndex:1];
NSString *value = [self valueForKey:key];
keyValue = [keyValue stringByAppendingString:[NSString stringWithFormat:@"%@=%@\n",key,value]];
}
NSString *name = NSStringFromClass([self class]);
return [NSString stringWithFormat:@"\n<****\n%@: %@****>",name,keyValue];
}
@end
继承BaseModel
继承BaseModel ,你即将给你的Model插上翅膀
#import "BaseModel.h"
@interface HomeModel : BaseModel
@property (nonatomic,copy)NSString *name;
@property (nonatomic,copy)NSString *sex;
@property (nonatomic,assign)NSInteger age;
@end
#import "HomeModel.h"
@implementation HomeModel
@end
验证是否可以飞行
自定义对象写入沙盒 (复杂对象->归档->NSData->writeToFile)
(1)先归档 (遵循NSCoding协议,实现encodeWithCoder、initWithCoder方法)
(2)后写入
- (void)viewDidLoad {
[super viewDidLoad];
HomeModel *model = [[HomeModel alloc]init];
model.name = @"iOSCoderZhao";
model.sex = @"男";
model.age = 18;
// 写入沙盒
[self archiverWithModel:model];
// 沙盒读取
[self enchiver];
}
- (void)archiverWithModel:(HomeModel *)model
{
// 归档
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:data];
[archiver encodeObject:model forKey:@"model"];
[archiver finishEncoding];//结束归档
// 存储路径(写入document路径)
NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *pathString = [document stringByAppendingPathComponent:@"dataPath"];
[data writeToFile:pathString atomically:YES];
}
- (void)enchiver
{
// 路径
NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *pathString = [document stringByAppendingPathComponent:@"dataPath"];
NSData *data = [NSData dataWithContentsOfFile:pathString];
// 解档
NSKeyedUnarchiver *unArchiver = [[NSKeyedUnarchiver alloc]initForReadingWithData:data];
HomeModel *model = [unArchiver decodeObjectForKey:@"model"];
[unArchiver finishDecoding];
NSLog(@"%@",model);
}
控制台结果
<****
HomeModel:
name=iOSCoderZhao
sex=男
age=18
****>