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)")
}
}
}
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)")
}
}
}
Swift が弱いポインターを処理する方法 (protip: 処理しない) により、クラスはこのコードでオーバーリリースされることに注意してください。ブリッジングとSwift へのポインタ についてSR-1068を開きました。ポインターは としてブリッジされますが、ポインターは としてブリッジされます。これにより、オーバーリリースが発生します。__weak
__unsafe_unretained
__weak
UnsafeMutablePointer
__unsafe_unretained
AutoreleasingUnsafeMutablePointer
幸いなことに、Classes は release で何もしないので、このコードは少なくとも今のところ比較的安全です。