具體實(shí)現(xiàn)代碼請看GItHub如果覺得不錯,請start一下,謝謝!
1.如何快速生成Plist文件屬性名
- 實(shí)現(xiàn)原理:通過遍歷字典,判斷類型,拼接字符串
// 拼接屬性字符串代碼
NSMutableString *strM = [NSMutableString string];
// 1.遍歷字典,把字典中的所有key取出來,生成對應(yīng)的屬性代碼
[dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
NSString *type;
if ([obj isKindOfClass:NSClassFromString(@"__NSCFString")]) {
type = @"NSString";
}else if ([obj isKindOfClass:NSClassFromString(@"__NSCFArray")]){
type = @"NSArray";
}else if ([obj isKindOfClass:NSClassFromString(@"__NSCFNumber")]){
type = @"int";
}else if ([obj isKindOfClass:NSClassFromString(@"__NSCFDictionary")]){
type = @"NSDictionary";
}else if ([obj isKindOfClass:NSClassFromString(@"__NSCFBoolean")]){
type = @"BooL";
}
// 屬性字符串
NSString *str;
if ([type containsString:@"NS"]) {
str = [NSString stringWithFormat:@"@property (nonatomic, strong) %@ *%@;",type,key];
}else{
str = [NSString stringWithFormat:@"@property (nonatomic, assign) %@ %@;",type,key];
}
// 每生成屬性字符串,就自動換行。
[strM appendFormat:@"\n%@\n",str];
}];
// 把拼接好的字符串打印出來,就好了。
NSLog(@"%@",strM);
打印結(jié)果

2.KVC實(shí)現(xiàn)字典轉(zhuǎn)模型
- KVC弊端
- 模型中屬性必須和字典的key一致,否則就報(bào)錯
- 如果不一致,系統(tǒng)會調(diào)用
setValue: forUndefinedKey: - 解決辦法,只需要重寫
setValue: forUndefinedKey:即可
- (void)setValue:(id)value forUndefinedKey:(NSString *)key
{
}
3.RunTime實(shí)現(xiàn)字典轉(zhuǎn)模型
- 實(shí)現(xiàn)思路:遍歷模型中所有屬性,根據(jù)模型的屬性名去字典中查找key,取出對應(yīng)的的值,給模型的屬性賦值
一級轉(zhuǎn)換
class_copyIvarList(self, &count)該方法第一個參數(shù)是要獲取哪個類中的成員屬性,第二個參數(shù)是這個類中有多少成員屬性,需要傳入地址,返回值Ivar是個數(shù)組,會將所有成員屬性放入這個數(shù)組中
id objc = [[self alloc] init];
unsigned int count;
// 獲取類中的所有成員屬性
Ivar *ivarList = class_copyIvarList(self, &count);
for (int i = 0; i < count; i++) {
Ivar ivar = ivarList[i];
// 獲取成員屬性名
NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)];
// 處理成員屬性名->字典中的key
// 從第一個角標(biāo)開始截取
NSString *key = [name substringFromIndex:1];
// 根據(jù)成員屬性名去字典中查找對應(yīng)的value
id value = dict[key];
二級轉(zhuǎn)換
判斷字典中是否存在字典,如果存在,轉(zhuǎn)為模型
字典屬性生成的是@"@\"xxxx\""類型,需要裁減為@"xxxx"
if ([value isKindOfClass:[NSDictionary class]]) {
// 獲取成員屬性類型
NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)];
// 生成的是這種@"@\"User\"" 類型 -》 @"User" 在OC字符串中 \" -> ",\是轉(zhuǎn)義的意思,不占用字符
// 裁剪類型字符串
NSRange range = [type rangeOfString:@"\""];
type = [type substringFromIndex:range.location + range.length];
range = [type rangeOfString:@"\""];
// 裁剪到哪個角標(biāo),不包括當(dāng)前角標(biāo)
type = [type substringToIndex:range.location];
// 根據(jù)字符串類名生成類對象
Class modelClass = NSClassFromString(type);
if (modelClass) {
value = [modelClass modelWithDict:value];
}
}
三級轉(zhuǎn)換
通過給分類添加一個協(xié)議,來實(shí)現(xiàn)將數(shù)組中的字典轉(zhuǎn)為模型
if ([value isKindOfClass:[NSArray class]])
{
// 判斷對應(yīng)類有沒有實(shí)現(xiàn)字典數(shù)組轉(zhuǎn)模型數(shù)組的協(xié)議
if ([self respondsToSelector:@selector(arrayContainModelClass)]) {
// 轉(zhuǎn)換成id類型,就能調(diào)用任何對象的方法
id idSelf = self;
// 獲取數(shù)組中字典對應(yīng)的模型
NSString *type = [idSelf arrayContainModelClass][key];
// 生成模型
Class classModel = NSClassFromString(type);
NSMutableArray *arrM = [NSMutableArray array];
// 遍歷字典數(shù)組,生成模型數(shù)組
for (NSDictionary *dict in value) {
// 字典轉(zhuǎn)模型
id model = [classModel modelWithDict:dict];
[arrM addObject:model];
}
// 把模型數(shù)組賦值給value
value = arrM;
}
}
還在學(xué)習(xí)中,略有錯誤請大家指出,謝謝!