Ios 获取所有本机类的列表

Ios 获取所有本机类的列表,ios,objective-c,nsobject,dladdr,Ios,Objective C,Nsobject,Dladdr,我想获取我已加载到iOS项目中的所有本机类(NSString、NSNumber、int、float、NSSet、NSDictionary) i、 例如,如果我创建了一个名为“TestClass”的自定义类,我不希望它被列出 我已经有了一个代码,但它返回所有加载类的名称,我可以修改代码,将列表限制为仅本地类吗 #import <objc/runtime.h> #import <dlfcn.h> #import <mach-o/ldsyms.h> unsign

我想获取我已加载到iOS项目中的所有本机类(NSString、NSNumber、int、float、NSSet、NSDictionary)

i、 例如,如果我创建了一个名为“TestClass”的自定义类,我不希望它被列出

我已经有了一个代码,但它返回所有加载类的名称,我可以修改代码,将列表限制为仅本地类吗

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


unsigned int count;
const char **classes;
Dl_info info;

dladdr(&_mh_execute_header, &info);
classes = objc_copyClassNamesForImage(info.dli_fname, &count);

for (int i = 0; i < count; i++) {
  NSLog(@"Class name: %s", classes[i]);
  Class class = NSClassFromString ([NSString stringWithCString:classes[i] encoding:NSUTF8StringEncoding]);
  // Do something with class

}
#导入
#进口
#进口
无符号整数计数;
常量字符**类;
Dl_信息;
dladdr(和mh执行头和信息);
classes=objc_copyClassNamesForImage(info.dli_fname,&count);
for(int i=0;i
您将使用

int numClasses;
Class * classes = NULL;

classes = NULL;
numClasses = objc_getClassList(NULL, 0);

if (numClasses > 0 )
{
    classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * numClasses);
    numClasses = objc_getClassList(classes, numClasses);
    for (int i = 0; i < numClasses; i++) {
        Class c = classes[i];
        NSLog(@"%s", class_getName(c));
    }
    free(classes);
}

适用于未从应用程序加载的所有类。

以下是一个使用Swift 3的纯Swift解决方案:

var numClasses: Int32 = 0
var allClasses: AutoreleasingUnsafeMutablePointer<AnyClass?>? = nil
defer {
    allClasses = nil
}

numClasses = objc_getClassList(nil, 0)

if numClasses > 0 {
    var ptr = UnsafeMutablePointer<AnyClass?>.allocate(capacity: Int(numClasses))
    defer {
        ptr.deinitialize()
        ptr.deallocate(capacity: Int(numClasses))
    }
    allClasses = AutoreleasingUnsafeMutablePointer<AnyClass?>(ptr)
    numClasses = objc_getClassList(allClasses, numClasses)

    for i in 0 ..< numClasses {
        if let currentClass: AnyClass = allClasses?[Int(i)] {
            print("\(currentClass)")
        }
    }
}
var numclass:Int32=0
var allClasses:AutoreleasingUnsafemutable关于桥接的指针
\uuuu弱
\uu不安全\u未保留
指向Swift的指针
\uu弱
指针作为
不安全指针
桥接,而
\uu不安全指针
未维护的
指针作为
自动释放不安全指针
桥接,这会导致过度弹性


幸运的是,这段代码相对安全,至少目前是这样。

使用运行时,可以:

目标-C

#import <objc/runtime.h>

- (void) printClassNames {
    int amountClasses = objc_getClassList(NULL, 0);
    printf("Amount of classes: %d", amountClasses);

    Class *classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * amountClasses);
    amountClasses = objc_getClassList(classes, amountClasses);

    for (int i = 0; i < amountClasses; i++) {
        Class class = classes[i];

        if ([NSBundle bundleForClass:class] != [NSBundle mainBundle]) { // restriction that pass classes from main bundle
            continue;
        }

        printf("Class name: %s", class_getName(class));

        [self printPropertyNamesForClass:class];
        [self printMethodNamesForClass:class];

    }

    free(classes);
}

- (void) printPropertyNamesForClass:(Class) class {
    uint count;
    objc_property_t* properties = class_copyPropertyList(class, &count);

    for (int i = 0; i < count ; i++) {

        const char* propertyName = property_getName(properties[i]);
        printf("\t Property name: %s \n", propertyName);
    }
    free(properties);
}

- (void) printMethodNamesForClass:(Class) class {
    //List of all methods
    unsigned int amountMethod = 0;
    Method *methods = class_copyMethodList(class, &amountMethod);

    for (unsigned int i = 0; i < amountMethod; i++) {
        Method method = methods[i];

        printf("\t method named:'%s' \n", sel_getName(method_getName(method)));
    }

    free(methods);
}
#导入
-(void)printClassNames{
int amountClasses=objc_getClassList(NULL,0);
printf(“类别数量:%d”,类别数量);
类别*类别=(uu不安全的_u未维护的类别*)malloc(大小(类别)*数量类别);
amountClasses=objc_getClassList(类,amountClasses);
对于(int i=0;i
迅捷的

func printClassNames(){
让amountClasses=objc_getClassList(nil,0)
打印(“类别数量:\(amountClasses)”)
var classes=[AnyClass](重复:NSObject.self,count:Int(amountClasses))
classes.WITHUNSAFEMTABLEBUFFERPOINTER{buffer in
让autoreleasingPointer=AutoreleasingUnsafemtablePointer(buffer.baseAddress)
objc_getClassList(自动删除指针,数量类)
}
对于类中的currentClass{
保护包(for:currentClass)=Bundle.main else{continue}
打印(“类名:\(currentClass)”)
printPropertyNamesForClass(currentClass)
printMethodNamesForClass(currentClass)
}
}
func printPropertyNamesForClass(currentClass:AnyClass){
变量计数=UInt32()
让propertyList=class\u copyPropertyList(currentClass,&count)
让intCount=Int(count)
guard let properties=propertyList,intCount>0 else{return}
对于0中的i..0 else{return}
var ptr=方法
对于0..
int,float不是类。@MartinR但在上述情况下,它们也会进入列表!!如果我运行您的代码,我只会得到应用程序中定义的类(AppDelegate、ViewController)。你想要在任何框架中定义的所有类(Foundation、CoreFoundation、UIKit、WebKit、QuartzCore等)还是“本机类”是什么意思?@MartinR no dude我只是指“上述情况”-这就是我想要做的…也就是说,我想要列出基本数据类型。。但是上面的代码将得到执行的类(意味着已编译,而不是在包中)。。。您想要在任何框架(Foundation、CoreFoundation、UIKit、WebKit、QuartzCore等)中定义的所有类,还是“本机类”是什么意思?确切地说:)你能猜出我为什么需要这个吗?我一直在尝试运行这个,但当我尝试运行调用它的单元测试时,它不会编译。它在iOS8.4中工作吗?还将考虑使用它来替换下面的代码。你们知道上面的代码是否会提高性能吗?Stackoverflow说是为了避免感谢…但我要说的是感谢:)有没有办法从我这里得到的列表中过滤出私有类和公共类?嘿,Martin,我尝试了一个简单的解决方案。你介意看一看并给我一些反馈吗?谢谢它应该是
0..
。分配的内存不会被释放。比较一下,马丁纳我换了t
var numClasses: Int32 = 0
var allClasses: AutoreleasingUnsafeMutablePointer<AnyClass?> = nil
defer {
    allClasses = nil
}

numClasses = objc_getClassList(nil, 0)

if numClasses > 0 {
    var ptr = UnsafeMutablePointer<AnyClass>.alloc(Int(numClasses))
    defer {
        ptr.destroy()
        ptr.dealloc(Int(numClasses))
        ptr = nil
    }
    allClasses = AutoreleasingUnsafeMutablePointer<AnyClass?>.init(ptr)
    numClasses = objc_getClassList(allClasses, numClasses)

    for i in 0 ..< numClasses {
        if let currentClass: AnyClass = allClasses[Int(i)] {
            print("\(currentClass)")
        }
    }
}
#import <objc/runtime.h>

- (void) printClassNames {
    int amountClasses = objc_getClassList(NULL, 0);
    printf("Amount of classes: %d", amountClasses);

    Class *classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * amountClasses);
    amountClasses = objc_getClassList(classes, amountClasses);

    for (int i = 0; i < amountClasses; i++) {
        Class class = classes[i];

        if ([NSBundle bundleForClass:class] != [NSBundle mainBundle]) { // restriction that pass classes from main bundle
            continue;
        }

        printf("Class name: %s", class_getName(class));

        [self printPropertyNamesForClass:class];
        [self printMethodNamesForClass:class];

    }

    free(classes);
}

- (void) printPropertyNamesForClass:(Class) class {
    uint count;
    objc_property_t* properties = class_copyPropertyList(class, &count);

    for (int i = 0; i < count ; i++) {

        const char* propertyName = property_getName(properties[i]);
        printf("\t Property name: %s \n", propertyName);
    }
    free(properties);
}

- (void) printMethodNamesForClass:(Class) class {
    //List of all methods
    unsigned int amountMethod = 0;
    Method *methods = class_copyMethodList(class, &amountMethod);

    for (unsigned int i = 0; i < amountMethod; i++) {
        Method method = methods[i];

        printf("\t method named:'%s' \n", sel_getName(method_getName(method)));
    }

    free(methods);
}
func printClassNames() {

    let amountClasses = objc_getClassList(nil, 0)
    print("Amount of classes: \(amountClasses)")

    var classes = [AnyClass](repeating: NSObject.self, count: Int(amountClasses))
    classes.withUnsafeMutableBufferPointer { buffer in
        let autoreleasingPointer = AutoreleasingUnsafeMutablePointer<AnyClass>(buffer.baseAddress)
        objc_getClassList(autoreleasingPointer, amountClasses)
    }

    for currentClass in classes {

        guard Bundle(for: currentClass) == Bundle.main else {continue}
        print("Class name:\(currentClass)")

        printPropertyNamesForClass(currentClass)
        printMethodNamesForClass(currentClass)
    }

}

func printPropertyNamesForClass(_ currentClass : AnyClass) {
    var count = UInt32()
    let propertyList = class_copyPropertyList(currentClass, &count)
    let intCount = Int(count)

    guard let properties = propertyList, intCount > 0 else {return}

    for i in 0 ..< intCount {
        let property : objc_property_t = properties[i]

        let nameCString = property_getName(property)
        print("\t Property name:\(String(cString: nameCString))");

    }

    free(properties)
}

func printMethodNamesForClass(_ currentClass: AnyClass) {
    var methodCount: UInt32 = 0
    let methodList = class_copyMethodList(currentClass, &methodCount)

    guard let methods = methodList, methodCount > 0 else {return}

    var ptr = methods
    for _ in 0 ..< methodCount {

        let sel = method_getName(ptr.pointee)
        ptr = ptr.successor()

        let nameCString = sel_getName(sel)

        print("\t method named:\(String(cString: nameCString))");
    }

}