2013-10-10 134 views
6

我想所有的本地類(的NSString,NSNumber的,整數,浮點,NSSet中,NSDictionary的),我已經加載到我的iOS項目..獲取所有本地類的列表

也就是說,如果我創建一個名爲「TestClass」的自定義類我不希望它列出...

我已經得到了一個代碼,但它返回所有加載的類的名稱任何方式我可以修改代碼來限制列表只有Native類?

#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 

} 
+0

int,float不是類。 –

+0

@MartinR,但也會進入上面案例的列表! – Raon

+0

如果我運行你的代碼,我只獲得* app中定義的類(AppDelegate,ViewController)。你是否想要在任何框架(Foundation,CoreFoundation,UIKit,WebKit,QuartzCore,...)中定義的所有類,或者「native class」是什麼意思? –

回答

6

你會(從objc_getClassList文件代碼。)獲得所有加載的類與

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); 
} 

要限制列表中,可以檢查從中類被加載,例如

​​

對於沒有從您的應用程序加載的所有類。

+0

Stackoverflow說避免謝謝...但我必須說謝謝:) – Raon

+0

是否有辦法過濾掉我在這裏得到的列表中的私人和公共類? –

+0

嘿馬丁,我試過你的答案的純Swift解決方案[這裏](http://stackoverflow.com/a/36181261/2415822)。你介意看看並給我一些反饋?謝謝! – JAL

3

下面是用斯威夫特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)") 
     } 
    } 
} 

與斯威夫特原液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)") 
     } 
    } 
} 

注意的是,由於道路斯威夫特處理弱指針(普羅蒂普:它不),你的類將被這個代碼過度發佈。我已經打開SR-1068關於橋接__weak__unsafe_unretained指向Swift的指針。 __weak指針被橋接爲UnsafeMutablePointer,而__unsafe_unretained指針被橋接爲AutoreleasingUnsafeMutablePointer,這導致過度增強酶。

幸運的是,Classes don't do anything on release,所以這段代碼是相對安全的,至少現在是這樣。

+0

它應該是'0 ..

+0

@MartinR我改變了你的評論for循環。我不能在指針上調用'dealloc',因爲我正在使用'AutoreleasingUnsafeMutablePointer'而不是'UnsafeMutablePointer',所以應該自動釋放內存嗎? – JAL

+0

我不這麼認爲。查看鏈接代碼。 –