美文网首页
runtime使用篇: objc_getClassList 和

runtime使用篇: objc_getClassList 和

作者: 缔造福地 | 来源:发表于2016-12-17 17:07 被阅读2381次
    前言:
    • 本篇文章将介绍以下两个相关的runtime函数的使用
      int objc_getClassList(Class *buffer, int bufferCount)
      Class *objc_copyClassList(unsigned int *outCount)
    1. int objc_getClassList(Class *buffer, int bufferCount)

    分析:该函数的作用是获取已经注册的类,它需要传入两个参数,第一个参数 buffer :已分配好内存空间的数组,第二个参数 bufferCount :数组中可存放元素的个数,返回值是注册的类的总数。
    当参数 bufferCount 值小于注册的类的总数时,获取到的是注册类的集合的任意子集
    第一个参数传 NULL 时将会获取到当前注册的所有的类,此时可存放元素的个数为0,因此第二个参数可传0,返回值为当前注册的所有类的总数。

    代码示例如下:(参考自runtime源码

    int numClasses = 0, newNumClasses = objc_getClassList(NULL, 0); // 1
    Class *classes = NULL; // 2
    while (numClasses < newNumClasses) { // 3
        numClasses = newNumClasses; // 4
        classes = (Class *)realloc(classes, sizeof(Class) * numClasses); // 5
        newNumClasses = objc_getClassList(classes, numClasses); // 6
        
        for (int i = 0; i < numClasses; i++) { // 7
            const char *className = class_getName(classes[i]); // 8
            NSLog(@"%s", className); // 9
        } // 10
        
    } // 11
    free(classes); // 12
    

    说明:
    第1行代码中的 objc_getClassList 函数是为了获取到当前注册的所有类的总个数 newNumClasses
    第5行代码是根据 newNumClasses 调整数组 classes 的空间
    第6行代码是向已分配好内存空间的数组 classes 中存放元素
    第7-10行代码是用 class_getName 函数获取每个类的名称

    打印结果如下:

    runtime[53022:5619738] UIActivityIndicatorViewAccessibility
    runtime[53022:5619738] CTRadioAccessTechnology
    runtime[53022:5619738] _UIRefreshControlDefaultContentView
    runtime[53022:5619738] AVAssetWriterInputPixelBufferAdaptor
    runtime[53022:5619738] AXDialectMap
    runtime[53022:5619738] UIMutableApplicationSceneClientSettings
    runtime[53022:5619738] CIPhotoGrain
    runtime[53022:5619738] DOMTextEvent
    runtime[53022:5619738] UIKBBlurredKeyView
    runtime[53022:5619738] CUIPSDGradientLayer
    ...省略大部分
    

    另外,利用这个函数也可以获取到某一个类的所有子类,在上述代码的第9行和第10行之间添加如下代码即可:

    if (class_getSuperclass(classes[i]) == [UIScrollView class]) {
        NSLog(@"subclass of UIScrollView : %s", className);
    }
    

    打印结果如下:

    runtime[53871:5643679] subclass of UIScrollView : _UIEmojiScrollView
    runtime[53871:5643679] subclass of UIScrollView : UIPrinterSetupPINScrollView
    runtime[53871:5643679] subclass of UIScrollView : _UICompatibilityTextView
    runtime[53871:5643679] subclass of UIScrollView : UITableViewWrapperView
    runtime[53871:5643679] subclass of UIScrollView : UIPageControllerScrollView
    runtime[53871:5643679] subclass of UIScrollView : _UIQueuingScrollView
    runtime[53871:5643679] subclass of UIScrollView : UITableView
    runtime[53871:5643679] subclass of UIScrollView : UICollectionView
    runtime[53871:5643679] subclass of UIScrollView : UIWebScrollView
    runtime[53871:5643679] subclass of UIScrollView : UIFieldEditor
    runtime[53871:5643679] subclass of UIScrollView : UITextView
    runtime[53871:5643679] subclass of UIScrollView : UIWebOverflowScrollView
    runtime[53871:5643679] subclass of UIScrollView : _UIAlertControllerShadowedScrollView
    
    2. Class *objc_copyClassList(unsigned int *outCount)

    该函数的作用是获取所有已注册的类,和上述函数 objc_getClassList 参数传入 NULL0 时效果一样,代码相对简单:

    unsigned int outCount;
    Class *classes = objc_copyClassList(&outCount);
    for (int i = 0; i < outCount; i++) {
        NSLog(@"%s", class_getName(classes[i]));
    }
    free(classes);
    

    相关文章

      网友评论

          本文标题:runtime使用篇: objc_getClassList 和

          本文链接:https://www.haomeiwen.com/subject/kwxomttx.html