需要本地存儲一些數據,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"];
}