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.