1、正常寫法
1> ?.h 中聲明協議
@interface PersonKeyedArchiver : NSObject?<NSCoding>
2>.h中聲明屬性
@property (nonatomic,strong)NSString *name;
@property (nonatomic,assign)int ?age;
3>.m中寫 ?"歸檔"+"解檔"方法
- ?(void)encodeWithCoder:(NSCoder *)aCoder {
// 歸檔姓名(NSString 對象)
[aCoder encodeObject:self.name forKey:@"name"];
// 歸檔年齡(基本數據類型,如果是其它基本數據類型調用相應的encode方法)
[aCoder encodeInt:self.age forKey:@"age"];
}
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
if(self = [super init]) {
//歸檔的key 寫的什么 對應屬性解檔key就寫什么
self.name = [aDecoder decodeObjectForKey:@"name"];
self.age = [aDecoder decodeIntForKey:@"age"];
}?return self;
}
2、Runtime 寫法
? ? ? 和普通寫法的 步驟 1> 2> 不變,第三步驟修改(不需要關注步驟 2>中聲明了什么屬性-->Runtime獲取)
3>.m中Runtime寫"歸檔"+"解檔"方法
導入頭文件
#import <objc/runtime.h>
//歸檔
- (void)encodeWithCoder:(NSCoder *)aCoder{
? ? ? ? ? ?unsigned int count =0;
? ? ? ? ? ? Ivar *ivars = class_copyIvarList([<#PersonKeyedArchiver#> class], &count);//傳遞count的地址,修改count值
? ? ? ? ? ? for (int i =0; i<count;i++){
? ? ? ? ? ? ? ? ? ?Ivar ivar =ivars[i];//得到成員變量對象(內存位置)
? ? ? ? ? ? ? ? ? const char *name = ivar_getName(ivar);//得到成員變量名稱
? ? ? ? ? ? ? ? ? NSString *key = [NSString stringWithUTF8String:name];
? ? ? ? ? ? ? ? ? [aCoder encodeObject:[self valueForKey:key] forKey:key];//KVC
} ? ? ? ? ? ?free(ivars);//OC 的ARC只管理OC對象內存,這里C創建的所以要釋放
}
//解檔
- (instancetype)initWithCoder:(NSCoder *)aDecoder{
? ? ? ? ? ? ? ? if (self = [super init]) {
? ? ? ? ? ? ? ? unsigned int count = 0;
? ? ? ? ? ? ? ? Ivar *ivars = class_copyIvarList([<#PersonKeyedArchiver#> class], &count);
? ? ? ? ? ? ? ? for (int i =0 ; i<count;i++){
? ? ? ? ? ? ? ? Ivar ivar = ivars[i];//得到成員變量對象(內存位置)
? ? ? ? ? ? ? ?const char *name =ivar_getName(ivar);//得到成員變量名稱
? ? ? ? ? ? ? ?NSString *key =[NSString stringWithUTF8String:name];
? ? ? ? ? ? ? ?id value = [aDecoder decodeObjectForKey:key];//KVC
? ? ? ? ? ? ? ?[self setValue:value forKey:key];
} ? ? ? ? ? ? ? free(ivars);//OC 的ARC只管理OC對象內存,這里C創建的所以要釋放
} ? ? ?return self;
}
存儲
#define UserNameFileName [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"userName.data"]
[NSKeyedArchiver archiveRootObject:<#PersonKeyedArchiver#> toFile:UserNameFileName];
讀取
? ? BOOL blHave = [[NSFileManager defaultManager] fileExistsAtPath:UserNameFileName];
? ? if (blHave) {
? ? ? ? <#PersonKeyedArchiver#> *userNameModel = [NSKeyedUnarchiver unarchiveObjectWithFile:UserNameFileName];
}
刪除
?BOOL blHave=[[NSFileManager defaultManager] fileExistsAtPath:UserNameFileName];
? ? if(blHave) {
? ? ? ? NSFileManager* fileManager=[NSFileManagerdefaultManager];
? ? ? ? [fileManager removeItemAtPath:UserNameFileName error:nil];
? ? }
這個總結不錯:【IOS學習基礎】歸檔和解檔
數據本地存儲:數據持久化
大神的Runtime總結:測試用例RunTime gitHub地址
SHX_2017-01-28