【code_小馬】使用runtime實現(xiàn)自動歸檔和解檔的解決方法

我們是工程師 ——加油 碎税!

如果你實現(xiàn)過自定義模型數(shù)據(jù)持久化的過程,
那么你也肯定明白馏锡,如果一個模型有許多個屬性雷蹂,
那么我們需要對每個屬性都實現(xiàn)一遍encodeObject 和decodeObjectForKey方法,
如果這樣的模型又有很多個 假設(shè)現(xiàn)在有一個Movie類杯道,有3個屬性匪煌。
它的h文件這這樣的


#import <Foundation/Foundation.h>
//1. 如果想要當(dāng)前類可以實現(xiàn)歸檔與反歸檔,需要遵守一個協(xié)議NSCoding
@interface Movie : NSObject<NSCoding>

@property (nonatomic, copy) NSString *movieId;
@property (nonatomic, copy) NSString *movieName;
@property (nonatomic, copy) NSString *pic_url;
@end
  • 如果是正常寫法党巾, m文件應(yīng)該是這樣的:
#import "Movie.h"  
@implementation Movie  
 
- (void)encodeWithCoder:(NSCoder *)aCoder  
{  
    [aCoder encodeObject:_movieId forKey:@"id"];  
    [aCoder encodeObject:_movieName forKey:@"name"];  
    [aCoder encodeObject:_pic_url forKey:@"url"];  
 
}  
 
- (id)initWithCoder:(NSCoder *)aDecoder  
{  
    if (self = [super init]) {  
        self.movieId = [aDecoder decodeObjectForKey:@"id"];  
        self.movieName = [aDecoder decodeObjectForKey:@"name"];  
        self.pic_url = [aDecoder decodeObjectForKey:@"url"];  
    }  
    return self;  
}  
@end 

如果這里有100個虐杯、n多個屬性,那么我們也只能把所有屬性都給寫一遍昧港。
不過使用runtime后擎椰,這里就有更簡便的方法。

  • runtime的實現(xiàn)方式:

#import "Movie.h" 
#import <objc/runtime.h>  
@implementation Movie  
 
- (void)encodeWithCoder:(NSCoder *)encoder  
{  
    unsigned int count = 0;  
    Ivar *ivars = class_copyIvarList([Movie class], &count);  
 
    for (int i = 0; i<count; i++) {  
        // 取出i位置對應(yīng)的成員變量  
        Ivar ivar = ivars[i];  
        // 查看成員變量  
        const char *name = ivar_getName(ivar);  
        // 歸檔  
        NSString *key = [NSString stringWithUTF8String:name];  
        id value = [self valueForKey:key];  
        [encoder encodeObject:value forKey:key];  
    }  
    free(ivars);  
}  
 
- (id)initWithCoder:(NSCoder *)decoder  
{  
    if (self = [super init]) {  
        unsigned int count = 0;  
        Ivar *ivars = class_copyIvarList([Movie class], &count);  
        for (int i = 0; i<count; i++) {  
        // 取出i位置對應(yīng)的成員變量  
        Ivar ivar = ivars[i];  
        // 查看成員變量  
        const char *name = ivar_getName(ivar);  
       // 歸檔  
       NSString *key = [NSString stringWithUTF8String:name];  
      id value = [decoder decodeObjectForKey:key];  
       // 設(shè)置到成員變量身上  
        [self setValue:value forKey:key];  
        }  
        free(ivars);  
    }   
    return self;  
}  
@end 
//這樣的方式實現(xiàn)创肥,不管有多少個屬性达舒,寫這幾行代碼就搞定了。
  • 功能我們已經(jīng)實現(xiàn)了叹侄,下面看看更加簡便的方法:兩句代碼搞定巩搏。

我們把encodeWithCoder 和 initWithCoder這兩個方法抽成宏

#import "Movie.h" 
#import <objc/runtime.h>  
 
#define encodeRuntime(A)  
 
unsigned int count = 0; 
Ivar *ivars = class_copyIvarList([A 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 = [self valueForKey:key];  
[encoder encodeObject:value forKey:key];  
}  
free(ivars);  
 
 
#define initCoderRuntime(A)   
  
if (self = [super init]) {  
unsigned int count = 0;  
Ivar *ivars = class_copyIvarList([A 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 = [decoder decodeObjectForKey:key]; 
[self setValue:value forKey:key]; 
}  
free(ivars);  
}  
return self;  
  

@implementation Movie  
 
- (void)encodeWithCoder:(NSCoder *)encoder  
 
{  
    encodeRuntime(Movie)  
}  
 
- (id)initWithCoder:(NSCoder *)decoder  
{  
    initCoderRuntime(Movie)  
}  
@end  

【code_小馬】iOS實用戰(zhàn)術(shù)

  • 晌午時光
    很喜歡的一篇文章,拿出來和大家分享

【第三集】

我的小手在被窩外面有點涼了趾代,剛想收回來贯底,如風(fēng)卻輕輕的拉住了我。我很開心撒强,緊緊的攥著他的手禽捆,不一會就睡著了∑冢    是夜胚想,我們相識的第一晚,就這樣手拉手的度過芽隆。   那年浊服,我12歲,魏如風(fēng)11歲胚吁⊙捞桑  我是附近最漂亮的女孩子,這是我之所以沒感覺不幸的另一個重要的原因腕扶。人不應(yīng)只看外貌的孽拷,但長得好的人會讓人更愿意了解內(nèi)在,于是更容易被發(fā)現(xiàn)優(yōu)點蕉毯,于是更被大家喜歡乓搬。我就是如此被街里的男孩子們寵愛著〈海  然而进肯,越長大,我身邊的朋友卻越少棉磨。他們都漸漸不再來小賣店找我了江掩,只有鄰街的阿福還總是興沖沖的跑來,送給我各種玻璃珠子乘瓤。直到有一天环形,連阿福也不來了,而我也終于發(fā)現(xiàn)了這個問題的謎底衙傀√б鳎  那天我在巷口看見了如風(fēng)攔住阿福....

文章第二集
文章第四集

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市统抬,隨后出現(xiàn)的幾起案子火本,更是在濱河造成了極大的恐慌,老刑警劉巖聪建,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钙畔,死亡現(xiàn)場離奇詭異,居然都是意外死亡金麸,警方通過查閱死者的電腦和手機擎析,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挥下,“玉大人揍魂,你說我怎么就攤上這事∨镂粒” “怎么了愉烙?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長解取。 經(jīng)常有香客問我步责,道長,這世上最難降的妖魔是什么禀苦? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任蔓肯,我火速辦了婚禮,結(jié)果婚禮上振乏,老公的妹妹穿的比我還像新娘蔗包。我一直安慰自己,他們只是感情好慧邮,可當(dāng)我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布调限。 她就那樣靜靜地躺著舟陆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪耻矮。 梳的紋絲不亂的頭發(fā)上秦躯,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機與錄音裆装,去河邊找鬼踱承。 笑死,一個胖子當(dāng)著我的面吹牛哨免,可吹牛的內(nèi)容都是我干的茎活。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼琢唾,長吁一口氣:“原來是場噩夢啊……” “哼载荔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起采桃,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤身辨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后芍碧,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體煌珊,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年泌豆,在試婚紗的時候發(fā)現(xiàn)自己被綠了定庵。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡踪危,死狀恐怖蔬浙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贞远,我是刑警寧澤畴博,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站蓝仲,受9級特大地震影響俱病,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜袱结,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一亮隙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧垢夹,春花似錦溢吻、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽犀盟。三九已至,卻和暖如春蝇狼,著一層夾襖步出監(jiān)牢的瞬間阅畴,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工题翰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留恶阴,地道東北人诈胜。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓豹障,卻偏偏與公主長得像,于是被迫代替她去往敵國和親焦匈。 傳聞我的和親對象是個殘疾皇子血公,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容