iOS 歸檔反歸檔的簡單使用

需要本地存儲一些數據,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"];
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容