6

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

}
4

3 に答える 3

6

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__weakUnsafeMutablePointer__unsafe_unretainedAutoreleasingUnsafeMutablePointer

幸いなことに、Classes は release で何もしないので、このコードは少なくとも今のところ比較的安全です。

于 2016-03-23T14:42:46.727 に答える