zoukankan      html  css  js  c++  java
  • 使用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
  • 相关阅读:
    浅谈Java 8的新特性和使用场景
    Oracle下通过EXPDP导出某用户下的所有表,实例
    官网下载I.MX6参考手册
    TFTP服务开启
    二、 U-Boot 命令使用
    CP15协处理器
    Linux内核配置Kconfig语法
    M.2接口是如何辨别插入的SSD是SATA协议还是NVME协议?
    SSH 服务开启
    一 、 UBOOT简介
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/11661872.html
Copyright © 2011-2022 走看看