ios 类别和类扩展
来源:互联网 发布:无锡网络开发有限公司 编辑:程序博客网 时间:2024/05/20 18:17
- 一自定义分类打印字典转模型的属性声明
- 核心思想
- 与KVC赋值的区别
- 二两种字典转模型的代码
- KVC方式字典转模型
- runtime字典转模型
- 具体使用
本文分为两部分:
一:教你怎样一部获取成员属性(通过NSObject+autoLogProperty分类)
二:对比KVC和runtime两种字典转模型的方法并抽取一个分类
一:自定义分类,打印字典转模型的属性声明
+ (void)createPropertyCodeWithDict:(NSDictionary *)dict{ NSMutableString *strM = [NSMutableString string]; // 遍历字典 [dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull propertyName, id _Nonnull value, BOOL * _Nonnull stop) { NSString *code; //__NSCFString <——> NSString类型 //__NSCFNumber <——> int类型 //__NSCFArray <——> NSArray类型 //__NSCFDictionary <——> NSDictionary类型 //__NSCFBoolean <——> BOOL类型 if ([value isKindOfClass:NSClassFromString(@"__NSCFString")]) { code = [NSString stringWithFormat:@"@property (nonatomic, strong) NSString *%@;",propertyName]; }else if ([value isKindOfClass:NSClassFromString(@"__NSCFNumber")]){ code = [NSString stringWithFormat:@"@property (nonatomic, assign) int %@;",propertyName]; }else if ([value isKindOfClass:NSClassFromString(@"__NSCFArray")]){ code = [NSString stringWithFormat:@"@property (nonatomic, strong) NSArray *%@;",propertyName]; }else if ([value isKindOfClass:NSClassFromString(@"__NSCFDictionary")]){ code = [NSString stringWithFormat:@"@property (nonatomic, strong) NSDictionary *%@;",propertyName]; }else if ([value isKindOfClass:NSClassFromString(@"__NSCFBoolean")]){ code = [NSString stringWithFormat:@"@property (nonatomic, assign) BOOL %@;",propertyName]; } [strM appendFormat:@"\n%@\n",code]; }]; NSLog(@"%@",strM);}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
1.核心思想:
1.遍历自定义类中的成员变量 2.将遍历获取的成员变量定为value,复制给类中的ivar.
2.与KVC赋值的区别:
KVC是调用`setValue: forKey: `的方法,将系统的成员变量作为value,自定义的属性为key 如果自定义的属性找不到就必须要调用 `- (void)setValue:(id)value forUndefinedKey:(NSString *)key;` 来处理报错。 但是runtime的字典转模型是将自定义属性生成的下划线成员变量变为key. `setValuesForKeysWithDictionary:`就不会出现找不到key而报错的问题了。
二、两种字典转模型的代码:
1.KVC方式字典转模型
+ (StatusModel *)statusWithDict:(NSDictionary *)dict{ StatusModel *statusModel = [[self alloc] init]; // KVC [statusModel setValuesForKeysWithDictionary:dict]; return statusModel;}// 解决KVC报错- (void)setValue:(id)value forUndefinedKey:(NSString *)key{//可以为空,表示不处理,也可以为做一些转换操作// if ([key isEqualToString:@"XXX"]) {// _### = [value integerValue];// }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
2.runtime字典转模型
+ (instancetype)modelWithDict:(NSDictionary *)dict { id objc = [[self alloc] init]; unsigned int count = 0; Ivar *ivarList = class_copyIvarList(self, &count); for (int i = 0; i < count; i++) { //获取属性名 Ivar ivar = ivarList[i]; //获取成员名 NSString *propertyName = [NSString stringWithUTF8String:ivar_getName(ivar)]; //获取key NSString *key = [propertyName substringFromIndex:1]; //取出下划线_ //获取字典中的value id value = dict[key]; //获取成员属性类型 NSString *propertyType = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)]; //此处为二级转换,如果里面的为字典类型,且属性类型为二级模型的名字,不为NSDictionary if ([value isKindOfClass:[NSDictionary class]] && ![propertyType containsString:@"NS"]) { // 需要字典转换成模型 // 转换成哪个类型 // 打印出来的值为 @"@\"User\"", 截取成User // 字符串截取 NSRange range = [propertyType rangeOfString:@"\""]; propertyType = [propertyType substringFromIndex:range.location + range.length]; //此时变为 User\"";,借着截取掉后面的\"" range = [propertyType rangeOfString:@"\""]; propertyType = [propertyType substringToIndex:range.location]; // 获取需要转换类的类对象 Class modelClass = NSClassFromString(propertyType); if (modelClass) { value = [modelClass modelWithDict:value]; } } if (value) { // KVC赋值:不能传空 [objc setValue:value forKey:key]; } } return objc;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
3.具体使用
- (void)viewDidLoad { [super viewDidLoad]; NSString *filePath = [[NSBundle mainBundle] pathForResource:@"status.plist" ofType:nil]; NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:filePath]; //log方法属性 NSArray *dictArr = dict[@"statuses"]; [[self class] createPropertyCodeWithDict:dictArr[0]]; //打印StatusModel的属性 [[self class] createPropertyCodeWithDict:dictArr[0][@"user"]]; //打印UserModel的属性 NSMutableArray *statuses = [NSMutableArray array]; // 遍历字典数组 for (NSDictionary *dict in dictArr) {// KVC字典转模型,调用setValueForKeyWithDictionary:方法// StatusModel *statusModel = [StatusModel statusWithDict:dict];// runtime字典转模型,调用分类方法 StatusModel *statusModel = [StatusModel modelWithDict:dict]; [statuses addObject:statusModel]; } NSLog(@"%@",statuses); self.dataArray = statuses;}//懒加载dataArray- (NSMutableArray *)dataArray{ if (!_dataArray) { _dataArray = [NSMutableArray array]; } return _dataArray;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
点击下载demo
注意:demo中的工具类可以抽取使用
(function () {('pre.prettyprint code').each(function () {
var lines =
for (i = 1; i <= lines; i++) {
};
$numbering.fadeIn(1700);
});
});
0 0
- iOS类别和类扩展
- ios 类别和类扩展
- ios 类别和扩展
- ios 类别和扩展
- ios 类别和扩展
- iOS 类别(catogry)和类扩展(extension)
- 类别和类扩展
- 类别和类扩展
- iOS - 类别与类扩展
- iOS类别和扩展(Category和Extension)
- iOS - Categories&&Extensions (类别和扩展)
- IOS中的类别(Category)和扩展(Extension)
- iOS类别(Category)和扩展(Extension)
- iOS 类别和扩展的区别
- ios中类别和扩展的区别
- 类别和类的扩展
- 【iOS沉思录】OC中的类扩展机制:Category类别和Extension类扩展
- iOS类别可以扩展类的属性
- CentOS 6上使用C++调用Redis
- 【Unity&NGUI】为什么把NGUI的UI制作为预制体,再生成到新场景,UI无法正常在Game视图显示
- 关于ZJOI2017day2的感想 #1
- boot-factory模式
- 安卓漫漫路之BitmapFactory高效加载Bitmap.
- ios 类别和类扩展
- WIFI 模块上传服务器显示曲线
- uva10791 唯一分解定理
- 第三讲:index3控制指令.html
- 2017河南工业大学校赛 I 小天使改名
- matlab矩阵
- Parcelable 序列化集合List,数组 Array,布尔值 boolean 先将就看这两篇文章,后期整理
- Android RTMP直播推流方案选择
- c缺陷与陷阱