使用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

 

posted @ 2019-10-12 15:34  XYQ全哥  阅读(1468)  评论(0编辑  收藏  举报