Get List of all native classes
You would get all loaded classes with
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);
}
(Code from objc_getClassList documentation.)
To restrict the list, you can check the bundle from which the class was loaded, e.g.
Class c = classes[i];
NSBundle *b = [NSBundle bundleForClass:c];
if (b != [NSBundle mainBundle])
...
for all classes that are not loaded from your application.
Here's a pure Swift solution with Swift 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?>.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)")
}
}
}
Original solution with 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)")
}
}
}
Note that due to the way Swift handles weak pointers (protip: it doesn't), your classes will be overreleased with this code. I've opened SR-1068 about bridging __weak
and __unsafe_unretained
pointers to Swift. __weak
pointers are bridged as UnsafeMutablePointer
while __unsafe_unretained
pointers are bridged as AutoreleasingUnsafeMutablePointer
, which causes the overrelase.
Fortunately, Classes don't do anything on release, so this code is relatively safe, at least for now.