Runtime執行時用法1------獲取類屬性列表
阿新 • • 發佈:2019-02-18
提起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