Runtime之NSCoding的自動歸檔、接檔

有些初學者有可能在死記硬背Runtime的作用,為了應付面試,我在這就先簡單介紹一下為什么要有Runtime的NSCoding的自動歸檔、接檔(大牛可以略過)。

本地存儲數據的時候大概有四種方式

1、NSUserDefaults

2、NSKeyedArchiver

3、SQLite

4、Write

在這1、3、4就不多說了,用NSKeyedArchiver歸檔存儲數據的時候就需要遵循NSCoding協議了,要實現里面的歸檔、接檔

//歸檔方法

- (void)encodeWithCoder:(NSCoder *)aCoder

{

? ? //當學生被歸檔,學生要將成員都歸檔

? ? ? ? ?[aCoder encodeObject:self.name forKey:@"name"];

? ? ? ? ?[aCoder encodeInteger:self.age forKey:@"age"];

}

//解歸檔方法

- (id)initWithCoder:(NSCoder *)aDecoder

{

? ? ? ? ? if (self = [super init]) {

? ? ? ? ? ? ? ? ? //當學生被解歸檔,學生要將成員都解歸檔

? ? ? ? ? ? ? ? ? self.name = [aDecoder decodeObjectForKey:@"name"];

? ? ? ? ? ? ? ? ? self.age = [aDecoder decodeIntegerForKey:@"age"];

? ? ? ? ? ?}

? ? ? ? ? return self;

}

現在看起來還可以吧,這是因為數據少的情況下,如果數據有幾十條呢?寫幾十行這種代碼,你感覺怎么樣?只要錯一個字節,你這個數據就是沒有的。

這種情況就出現了今天要說的主題了:Runtime的自動歸檔、接檔。

Runtime有一個方法可以獲取當前類里面的屬性列表,既然成員變量都能拿到,每一個成員變量所對應的key以及value當然也可以拿到,這樣就不需要自己一行一行的去歸檔,接檔了。

#import "person.h"?

#import@implementation person

// 接檔讀數據

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

? ? ? ? ? ? ?if (self = [super init]) ?{

? ? ? ? ? ?/*

? ? ? ? ? ? ? OBJC_EXPORT Ivar *class_copyIvarList(Class cls, unsigned int *outCount)

? ? ? ? ? ? ? Class cls 表示獲取那一個類的屬性列表

? ? ? ? ? ? ? ?unsigned int *outCount 用于存儲獲取到屬性個數

? ? ? ? ? */

? ? ? ? ? unsigned int count = 0;

? ? ? ? ? Ivar *ivar = class_copyIvarList([self class], &count);

? ? ? ? ?for (int i = 0; i < count; i++) {

? ? ? ? ? ? ? ? //根據每一個屬性取出對應的key 注意key值是c語言的key

? ? ? ? ? ? ? ? ?Ivar iva = ivar[i];

? ? ? ? ? ? ? ? ?const charchar *key = ivar_getName(iva);

? ? ? ? ? ? ? ? ?// 轉換為oc?

? ? ? ? ? ? ? ? ?NSString *strName = [NSString stringWithUTF8String:key];?

? ? ? ? ? ? ? ? ?//進行解檔取值

? ? ? ? ? ? ? ? id value = [aDecoder decodeObjectForKey:strName];

? ? ? ? ? ? ? ? //利用KVC對屬性賦值

? ? ? ? ? ? ? ? ?[self setValue:value forKey:strName];

? ? ? ? ? }

? ? ? ? ? free(ivar);

? ?}

return self;

}

// 歸檔存數據

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

? ? ? ? ?unsigned int count;

? ? ? ? ?Ivar *ivar = class_copyIvarList([self class], &count);

? ? ? ? ?for (int i=0; i < count; i++) {

? ? ? ? ? ? ? ? ?Ivar iv = ivar[i];

? ? ? ? ? ? ? ? ?const charchar *name = ivar_getName(iv);

? ? ? ? ? ? ? ? ?NSString *strName = [NSString stringWithUTF8String:name];

? ? ? ? ? ? ? ? //利用KVC取值

? ? ? ? ? ? ? ? id value = [self valueForKey:strName];

? ? ? ? ? ? ? ? [aCoder encodeObject:value forKey:strName];

? ? ? ? ?}

? ? ? ? ? ?free(ivar);

}

需要注意的一個細節就是當涉及到Runtime的時候。一定要記得內存的釋放。Xcode的ARC只適用于OC,對于C的指針,要記得手動free。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容