使用Runtime的objc_copyClassNamesForImage和objc_getClassList获取类
一、介绍
objc_copyClassNamesForImage:拷贝动态库类列表,也即当前工程下自己创建的所有类
objc_getClassList:获取所有类列表,也即当前工程下所有类(含系统类、cocoPods类)
二、代码
// NSBundle+XYQInfomation.m // 运行时 #import "NSBundle+XYQInfomation.h" #import <objc/runtime.h> #import <dlfcn.h> /// 动态链接库头文件 #import <mach-o/ldsyms.h> ///内核动态系统库头文件 @implementation NSBundle (XYQInfomation) ///获取当前工程下自己创建的所有类 + (NSArray <Class> *)xyq_bundleOwnClassesInfo { NSMutableArray *resultArray = [NSMutableArray array]; unsigned int classCount; const char **classes; Dl_info info; ///_mh_execute_header : mach-o头部的地址 ///dladdr: 获取app的路径 dladdr(&_mh_execute_header, &info); ///拷贝动态库类列表 classes = objc_copyClassNamesForImage(info.dli_fname, &classCount); dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);///创建信号 dispatch_apply(classCount, dispatch_get_global_queue(0, 0), ^(size_t index) { ///遍历 dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);///信号加锁 NSString *className = [NSString stringWithCString:classes[index] encoding:NSUTF8StringEncoding]; Class class = NSClassFromString(className); [resultArray addObject:class]; dispatch_semaphore_signal(semaphore);///信号释放锁 }); ///释放内存 free(classes); return resultArray.mutableCopy; } ///获取当前工程下所有类(含系统类、cocoPods类) + (NSArray <NSString *> *)xyq_bundleAllClassesInfo { NSMutableArray *resultArray = [NSMutableArray new]; ///获取所有类 int classCount = objc_getClassList(NULL, 0); ///分配内存 Class *classes = NULL; classes = (__unsafe_unretained Class *)malloc(sizeof(Class) *classCount); ///获取所有类 classCount = objc_getClassList(classes, classCount); dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);///创建信号 dispatch_apply(classCount, dispatch_get_global_queue(0, 0), ^(size_t index) { ///遍历 dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); ///信号加锁 Class class = classes[index]; NSString *className = [[NSString alloc] initWithUTF8String: class_getName(class)]; [resultArray addObject:className]; dispatch_semaphore_signal(semaphore);///信号释放锁 }); ///释放内存 free(classes); return resultArray.mutableCopy; }
三、演示
测试:
-(void)test_Objc_GetClassList { //全部类 //NSArray *classes = [NSBundle xyq_bundleAllClassesInfo]; //自定义类 NSArray *classes = [NSBundle xyq_bundleOwnClassesInfo]; for (NSString *className in classes) { NSLog(@"className = %@",className); } }
结果:
2019-10-12 15:27:43.443258+0800 运行时[12969:3179534] className = Person 2019-10-12 15:27:43.443411+0800 运行时[12969:3179534] className = TestObject 2019-10-12 15:27:43.443514+0800 运行时[12969:3179534] className = ViewController 2019-10-12 15:27:43.443599+0800 运行时[12969:3179534] className = DataTableViewController 2019-10-12 15:27:43.443687+0800 运行时[12969:3179534] className = Student 2019-10-12 15:27:43.443771+0800 运行时[12969:3179534] className = AppDelegate 2019-10-12 15:27:43.443883+0800 运行时[12969:3179534] className = NoDataEmptyView
程序猿神奇的手,每时每刻,这双手都在改变着世界的交互方式!