Runtime获取类的属性列表和方法列表
Runtime获取类的属性列表和方法列表
Runtime很强大,他使得OC中没有真正意义上的私有属性和私有方法,我们可以利用OC的运行时拿到一个类的任何方法和任何属性,然后动态的去调用方法,objc_megsend(),甚至可以在运行时动态的为一个类去添加属性和方法,此篇博客要学习的是两个知识点:
- 获取对象的所有属性
- 获取对象的所有方法
为了方便,我们可以在项目中为NSObject添加一个category,增加下面两个方法,这样我们就可以轻轻松松获得每个类的所以方法和所以属性了,记得导入runtime的头文件哦。
获取对象的所有属性、方法、属性和属性内容
NSObject+JGRuntime.h文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #import <Foundation/Foundation.h> @interface NSObject (JGRuntime) /* 获取对象的所有属性 */ +( NSArray *)getAllProperties; /* 获取对象的所有方法 */ +( NSArray *)getAllMethods; /* 获取对象的所有属性和属性内容 */ + ( NSDictionary *)getAllPropertiesAndVaules; @end |
NSObject+JGRuntime.m文件
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | #import "NSObject+JGRuntime.h" #import <objc/runtime.h> @implementation NSObject (JGRuntime) /* 获取对象的所有属性 */ +( NSArray *)getAllProperties { u_int count; // 传递count的地址过去 &count objc_property_t *properties =class_copyPropertyList([ self class ], &count); //arrayWithCapacity的效率稍微高那么一丢丢 NSMutableArray *propertiesArray = [ NSMutableArray arrayWithCapacity:count]; for ( int i = 0; i < count ; i++) { //此刻得到的propertyName为c语言的字符串 const char * propertyName =property_getName(properties[i]); //此步骤把c语言的字符串转换为OC的NSString [propertiesArray addObject: [ NSString stringWithUTF8String: propertyName]]; } //class_copyPropertyList底层为C语言,所以我们一定要记得释放properties // You must free the array with free(). free(properties); return propertiesArray; } /* 获取对象的所有方法 */ +( NSArray *)getAllMethods { unsigned int methodCount =0; Method* methodList = class_copyMethodList([ self class ],&methodCount); NSMutableArray *methodsArray = [ NSMutableArray arrayWithCapacity:methodCount]; for ( int i=0;i<methodCount;i++) { Method temp = methodList[i]; IMP imp = method_getImplementation(temp); SEL name_f = method_getName(temp); const char * name_s =sel_getName(method_getName(temp)); int arguments = method_getNumberOfArguments(temp); const char * encoding =method_getTypeEncoding(temp); NSLog (@ "方法名:%@,参数个数:%d,编码方式:%@" ,[ NSString stringWithUTF8String:name_s], arguments, [ NSString stringWithUTF8String:encoding]); [methodsArray addObject:[ NSString stringWithUTF8String:name_s]]; } free(methodList); return methodsArray; } /* 获取对象的所有属性和属性内容 */ + ( NSDictionary *)getAllPropertiesAndVaules { NSMutableDictionary *propsDic = [ NSMutableDictionary dictionary]; unsigned int outCount; objc_property_t *properties =class_copyPropertyList([ self class ], &outCount); for ( int i = 0; i<outCount; i++) { objc_property_t property = properties[i]; const char * char_f =property_getName(property); NSString *propertyName = [ NSString stringWithUTF8String:char_f]; id propertyValue = [ self valueForKey:( NSString *)propertyName]; if (propertyValue) { [propsDic setObject:propertyValue forKey:propertyName]; } } free(properties); return propsDic; } @end |
调用时:
包含头文件
#import "NSObject+JGRuntime.h"
直接调用
如我在一个控制器的导航栏按钮点击时调用时
JGLog(@"\n%@",[JGWorkLogViewController getAllMethods]);
打印结果是:
(
setupChildVces,
setupTitlesView,
setupContentView,
titleClick:,
setTitlesView:,
setIndicatorView:,
setSelectedButton:,
indicatorView,
selectedButton,
titlesView,
setNavItem,
rightItemBtnClick,
leftitemBtnClick,
loadCtrlWithLogTypeStr:,
setContentView:,
scrollViewDidEndDecelerating:,
scrollViewDidEndScrollingAnimation:,
didReceiveMemoryWarning,
viewDidLoad,
.cxx_destruct,
contentView,
)
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core内存结构体系(Windows环境)底层原理浅谈
· C# 深度学习:对抗生成网络(GAN)训练头像生成模型
· .NET 适配 HarmonyOS 进展
· .NET 进程 stackoverflow异常后,还可以接收 TCP 连接请求吗?
· SQL Server统计信息更新会被阻塞或引起会话阻塞吗?
· 传国玉玺易主,ai.com竟然跳转到国产AI
· 本地部署 DeepSeek:小白也能轻松搞定!
· 自己如何在本地电脑从零搭建DeepSeek!手把手教学,快来看看! (建议收藏)
· 我们是如何解决abp身上的几个痛点
· 普通人也能轻松掌握的20个DeepSeek高频提示词(2025版)