提起Runtime运行时很多初学者会望而却步, 但是仔细想想, 我们要读懂别人框架的实现原理, 这些东西还是需要去学习了, 正所谓, 怕什么什么就是你的缺点, 面对我们知识层面的不足, 我们一定要勇敢地去克服. 好了扯淡部分结束, 进入正题!
如标题所示, 本文将详细说明如何获取属性列表, 以及用途!
对于任何想要使用的东西, 第一件事就是导入头文件, Runtime也不例外. 我们通过Runtime的方法可以获取到对象的属性列表, 然后就可以通过kvc的方式动态的给类的属性赋值. 这种方法多用于字典转模型中!下面就是字典转模型的代码, 将此分类头文件导入到你的pch文件中, 你的所有继承自NSObject对象都有了,扩展类的方法!那么你在模型文件中就不用再写字典转模型的代码. 请阅读以下代码
头文件
//
// NSObject+JLExterntion.h
// NetNews
//
// Created by Wangjunling on 16/5/26.
// Copyright © 2016年 Wangjunling. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSObject (JLExterntion)
+ (instancetype)jl_objWithDic:(NSDictionary *)dic;
@end
实现文件
//
// NSObject+JLExterntion.m
// NetNews
//
// Created by Wangjunling on 16/5/26.
// Copyright © 2016年 Wangjunling. All rights reserved.
//
#import "NSObject+JLExterntion.h"
#import <objc/runtime.h>
@implementation NSObject (JLExterntion)
+ (instancetype)jl_objWithDic:(NSDictionary *)dic {
id object = [[self alloc] init];
//获取属性列表
NSArray *propertyList = [self jl_getProperties];
//此方法会引起崩溃崩溃原因不清楚
// [propertyList enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
// [object setValue:dic[obj] forKey:obj];
// }];
[dic enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
// 判断 key 是否在 proList 中
if ([propertyList containsObject:key]) {
// 说明属性存在,可以使用 `KVC` 设置数值
[object setValue:obj forKey:key];
}
}];
return object;
}
+ (NSArray *)jl_getProperties {
//用于存入属性数量
unsigned int outCount = 0;
//获取属性数组
objc_property_t *propertyList = class_copyPropertyList([self class], &outCount);
NSMutableArray *arrM = [NSMutableArray arrayWithCapacity:outCount];
//遍历数组
for (int i = 0; i < outCount; ++i) {
objc_property_t property = propertyList[i];
//获取属性名
const char *cName = property_getName(property);
//将其转换成c字符串
NSString *propertyName = [NSString stringWithCString:cName encoding:NSUTF8StringEncoding];
// 加入数组
[arrM addObject:propertyName];
}
//在使用了c函数的creat, copy等函数是记得手动释放,要不然会引起内存泄露问题
free(propertyList);
return arrM.copy;
}
@end