iOS 归档反归档的简单使用

2018-04-12  本文已影响33人  安静就好_

需要本地存储一些数据,NSUserDefaults支持的数据类型有:NSNumber(NSInteger、float、double),NSString,NSDate,NSArray,NSDictionary,BOOL.没有自定义的复杂对象,这个时候就需要归档反归档一下了。

1.从model下手,记得遵循NSCoding协议

@interface ZQWRenZhengFiveModel : NSObject<NSCoding>

/** 企业服务项目工作业绩id*/
@property(strong,nonatomic)NSString *objectId;
/** 服务师id*/
@property(strong,nonatomic)NSString *serverAttacheId;
/** 项目名称*/
@property(strong,nonatomic)NSString *name;
/** 项目承担单位名称*/
@property(strong,nonatomic)NSString *companyName;
/** 合同总额*/
@property(strong,nonatomic)NSString *rental;
/** 主要工作内容*/
@property(strong,nonatomic)NSString *jobContent;
/** 项目开始时间*/
@property(strong,nonatomic)NSString *startTime;
/** 项目结束时间*/
@property(strong,nonatomic)NSString *finishTime;
/** 完成情况*/
@property(strong,nonatomic)NSString *performance;
/** 备注*/
@property(strong,nonatomic)NSString *remark;

@end

.m文件 是不是很繁琐,runtime的用法下面介绍

-(void)encodeWithCoder:(NSCoder *)aCoder{

    [aCoder encodeObject:_objectId forKey:@"objectId"];
    [aCoder encodeObject:_serverAttacheId forKey:@"serverAttacheId"];
    [aCoder encodeObject:_name forKey:@"name"];
    [aCoder encodeObject:_companyName forKey:@"companyName"];
    [aCoder encodeObject:_rental forKey:@"rental"];
    [aCoder encodeObject:_jobContent forKey:@"jobContent"];
    [aCoder encodeObject:_startTime forKey:@"startTime"];
    [aCoder encodeObject:_finishTime forKey:@"finishTime"];
    [aCoder encodeObject:_performance forKey:@"performance"];
    [aCoder encodeObject:_remark forKey:@"remark"];


}

-(instancetype)initWithCoder:(NSCoder *)aDecoder{

    if (self = [super init]) {
        
        _objectId = [aDecoder decodeObjectForKey:@"objectId"];
        _serverAttacheId = [aDecoder decodeObjectForKey:@"serverAttacheId"];
        _name = [aDecoder decodeObjectForKey:@"name"];
        _companyName = [aDecoder decodeObjectForKey:@"companyName"];
        _rental = [aDecoder decodeObjectForKey:@"rental"];
        _jobContent = [aDecoder decodeObjectForKey:@"jobContent"];
        _startTime = [aDecoder decodeObjectForKey:@"startTime"];
        _finishTime = [aDecoder decodeObjectForKey:@"finishTime"];
        _performance = [aDecoder decodeObjectForKey:@"performance"];
        _remark = [aDecoder decodeObjectForKey:@"remark"];
        
    }

    return self;
}

model搞定之后,就可以开始使用了

存储数据

在这里,我把所要存储的model放到数组,然后直接调用下面的方法就可以了
/**
 归档数据

 @param dataArr 存储的数组
 */
-(void)writeClick:(NSMutableArray *)dataArr{

    NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject] stringByAppendingString:@"/ZQWRenZhengFive"];
    NSMutableData *data = [NSMutableData data];
    //创建归档对象
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:dataArr forKey:@"ZQWRenZhengFive"];
    
    [archiver finishEncoding];
    BOOL result = [data writeToFile:path atomically:YES];
    if (result) {
        NSLog(@"写入成功 :%@",path);
       // [[NSUserDefaults standardUserDefaults] setObject:@"ZQWRenZhengFive" forKey:@"ZQWRenZhengFive"];
    }
}

去数据,反归档

//路径
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)firstObject] stringByAppendingString:@"/ZQWRenZhengFive"];
//获取数据
NSData *myData = [NSData dataWithContentsOfFile:path];
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:myData];

_dataArr = [unarchiver decodeObjectForKey:@"ZQWRenZhengFive"];

[unarchiver finishDecoding];

上边操作model着实有点费劲,下面用runtime来搞一搞

写一个NSObject的延展
.h文件

引入runtime的头文件
#import <objc/runtime.h>
添加两个方法
//忽略属性
- (NSArray *)ignoredNames;
- (void)decode:(NSCoder *)aDecoder ;
- (void)encode:(NSCoder *)aCoder;

.m 文件

- (void)decode:(NSCoder *)aDecoder {
    // 一层层父类往上查找,对父类的属性执行归解档方法
    Class c = self.class;
    while (c &&c != [NSObject class]) {
        
        unsigned int outCount = 0;
        Ivar *ivars = class_copyIvarList(c, &outCount);
        for (int i = 0; i < outCount; i++) {
            Ivar ivar = ivars[i];
            NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
            
            // 如果有实现该方法再去调用
            if ([self respondsToSelector:@selector(ignoredNames)]) {
                if ([[self ignoredNames] containsObject:key]) continue;
            }
            
            id value = [aDecoder decodeObjectForKey:key];
            [self setValue:value forKey:key];
        }
        free(ivars);
        c = [c superclass];
    }
    
}

- (void)encode:(NSCoder *)aCoder {
    // 一层层父类往上查找,对父类的属性执行归解档方法
    Class c = self.class;
    while (c &&c != [NSObject class]) {
        
        unsigned int outCount = 0;
        Ivar *ivars = class_copyIvarList([self class], &outCount);
        for (int i = 0; i < outCount; i++) {
            Ivar ivar = ivars[i];
            NSString *key = [NSString stringWithUTF8String:ivar_getName(ivar)];
            
            // 如果有实现该方法再去调用
            if ([self respondsToSelector:@selector(ignoredNames)]) {
                if ([[self ignoredNames] containsObject:key]) continue;
            }
            
            id value = [self valueForKeyPath:key];
            [aCoder encodeObject:value forKey:key];
        }
        free(ivars);
        c = [c superclass];
    }
}

nsobject的category写完之后,在model中使用

-(instancetype)initWithCoder:(NSCoder *)aDecoder{

    if (self = [super init]) {
    
     [ self decode:aDecoder];

}

-(void)encodeWithCoder:(NSCoder *)aCoder{

      [self encode:aCoder]

}
//实现该方法选择要忽略的属性
- (NSArray *)ignoredNames {
    return @[@"bone"];
}
上一篇下一篇

猜你喜欢

热点阅读