/ReflectionDemo

A demo for iOS was written by Objective-C. Get the list of all classes , includes created by ourselves and system, or excludes system created. 在Objective-C下获取app的所有的类的列表,有包括系统创建的类和自己创建的类列表,也有仅仅是自己创建的类列表, OC, ObjectiveC

Primary LanguageObjective-C

ReflectionDemo

A demo for iOS was written by Objective-C. Get the list of all classes , includes created by ourselves and system, or excludes system created.
在Objective-C下获取app的所有的类的列表,有包括系统创建的类和自己创建的类列表,也有仅仅是自己创建的类列表

提供测试的两个方法

1.可以获取(能直接被程序员修改的)共有类和私有类

2.可以获取库里的类,如:

 1). 通过Cocoapods导入的开源库 (通过test()和test2(),可以获取共有类和私有类)

 2). .a静态库 (通过test()和test2(),可以获取共有类和私有类)

 3). .framework静态库 (通过test()和test2(),可以获取共有类和私有类)

 4). .framework动态库(通过objc_getClassList()可以获取到,也就是测试方法test2()可以,而测试方法test()不可以)

3.不支持C++的类的获取

测试项目中库的类型说明

MyDynamicLib.framework 是动态库

MyFWorkLib.framework   是静态库

MyLib1.a               是静态库

test() 获取当前app运行过程中,由开发者(自己)创建的类的列表,不包括运行时系统创建的类

test2() 获取当前app运行时所用到所有的文件,包括 系统创建的类和开发者创建的类的 列表

请分开测试


#import "ViewController.h"
#import <objc/runtime.h>
#import <dlfcn.h>
#import <mach-o/ldsyms.h>
#import "MyClass2.h"


//http://stackoverflow.com/questions/19298553/get-list-of-all-native-classes
//这个stackoverflow上有说明

//方式1
//获取当前app运行过程中,由开发者创建的类的  列表
void test()
{
    unsigned int count;
    const char **classes;
    Dl_info info;

    //1.获取app的路径
    dladdr(&_mh_execute_header, &info);

    //2.返回当前运行的app的所有类的名字,并传出个数
    //classes:二维数组 存放所有类的列表名称
    //count:所有的类的个数
    classes = objc_copyClassNamesForImage(info.dli_fname, &count);

    for (int i = 0; i < count; i++) {
        //3.遍历并打印,转换Objective-C的字符串
        NSString *className = [NSString stringWithCString:classes[i] encoding:NSUTF8StringEncoding];
        Class class = NSClassFromString(className);
        NSLog(@"class name = %@", class);

        //根据类名调用
        if ([className isEqualToString:@"MyClass2"]) {
            MyClass2 *my = [[class alloc] init];

            //调用实例方法
            [my test1];

            //调用类方法
            [class test2];
        }

    }
}

//方式2
//获取当前app运行时所用到所有的文件,包括 系统创建的类和开发者创建的类的   列表
void test2()
{
    int numClasses;
    Class * classes = NULL;

    //1.获取当前app运行时所有的类,包括系统创建的类和开发者创建的类的  个数
    numClasses = objc_getClassList(NULL, 0);

    if (numClasses > 0 )
    {
        //2.创建一个可以容纳numClasses个的大小空间
        classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * numClasses);

        //3.重新获取具体类的列表和个数
        numClasses = objc_getClassList(classes, numClasses);

        //4.遍历
        for (int i = 0; i < numClasses; i++) {
            Class class = classes[i];
            const char *className = class_getName(class);
            NSLog(@"class name2 = %s", className);

            //根据类名调用
            if (strcmp(className, "MyClass2") == 0) {
                MyClass2 *my = [[class alloc] init];

                //调用实例方法
                [my test1];

                //调用类方法
                [class test2];
            }
        }
        free(classes);
    }
}

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    test();
    test2();


}

@end