我們是工程師 ——加油 碎税!
如果你實現(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)攔住阿福....