前言:
- 本篇文章将介绍以下两个相关的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
参数传入 NULL
和 0
时效果一样,代码相对简单:
unsigned int outCount;
Class *classes = objc_copyClassList(&outCount);
for (int i = 0; i < outCount; i++) {
NSLog(@"%s", class_getName(classes[i]));
}
free(classes);