获取所有本机类的列表

Rao*_*aon 6 objective-c nsobject ios dladdr

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

即,如果我创建了一个名为"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

}
Run Code Online (Sandbox Code Playgroud)

Mar*_*n R 6

你会得到所有加载的类

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);
}
Run Code Online (Sandbox Code Playgroud)

(来自objc_getClassList文档的代码.)

要限制列表,可以检查从中加载类的,例如

Class c = classes[i];
NSBundle *b = [NSBundle bundleForClass:c];
if (b != [NSBundle mainBundle])
    ...
Run Code Online (Sandbox Code Playgroud)

对于未从您的应用程序加载的所有类.


JAL*_*JAL 5

这是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)")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Swift 2.2 / Xcode 7.3的原始解决方案:

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)")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,由于Swift处理弱指针的方式(提示:不会),因此该代码将过度释放您的类。我已经打开了有关桥接和指向Swift的SR-1068。 指针被桥接为,而指针被桥接为,这导致了过度释放。__weak__unsafe_unretained__weakUnsafeMutablePointer__unsafe_unretainedAutoreleasingUnsafeMutablePointer

幸运的是,类在发布时不做任何事情,因此,至少在目前,此代码相对安全。