可以通过NSBundleDidLoadNotification
从包中获取类列表。但我无法弄清楚如何从已经加载的包中获取它们。 (与代码相同的捆绑包)
我正在尝试获取应用程序包的类列表。更具体地说,这些类只在我的应用程序二进制文件中。
我查看了objc_getClassList
,但它返回所有类,对我来说显然太重了。我需要轻量级的方法。我通过Google搜索找到了objc_copyClassNamesForImage
,但没有记录,我不知道如何安全使用它 。我想我可以尝试按常规使用它,但我想在去那里之前找到另一个更安全的选择。
答案 0 :(得分:4)
另一种选择是迭代遍历运行时注册的所有类,并在每个类上使用+[NSBundle bundleForClass:]
来确定它来自哪一个。然后,您可以根据结果将事物分组。
这样的事情:
@interface NSBundle (DDAdditions)
- (NSArray *)definedClasses_dd;
@end
@implementation NSBundle (DDAdditions)
- (NSArray *)definedClasses_dd {
NSMutableArray *array = [NSMutableArray array];
int numberOfClasses = objc_getClassList(NULL, 0);
Class *classes = calloc(sizeof(Class), numberOfClasses);
numberOfClasses = objc_getClassList(classes, numberOfClasses);
for (int i = 0; i < numberOfClasses; ++i) {
Class c = classes[i];
if ([NSBundle bundleForClass:c] == self) {
[array addObject:c];
}
}
free(classes);
return array;
}
@end
然后你可以打电话:
NSLog(@"%@", [[NSBundle mainBundle] definedClasses_dd]);
答案 1 :(得分:4)
试试这个魔法:
-(NSArray*)getClassNames{
NSMutableArray* classNames = [NSMutableArray array];
unsigned int count = 0;
const char** classes = objc_copyClassNamesForImage([[[NSBundle mainBundle] executablePath] UTF8String], &count);
for(unsigned int i=0;i<count;i++){
NSString* className = [NSString stringWithUTF8String:classes[i]];
[classNames addObject:className];
}
return classNames;
}
答案 2 :(得分:1)
我可以在这里找到函数objc_copyClassNamesForImage
的一些示例。
http://www.opensource.apple.com/source/objc4/objc4-493.9/test/weak.m
// class name list
const char *image = class_getImageName(objc_getClass("NotMissingRoot"));
testassert(image);
const char **names = objc_copyClassNamesForImage(image, NULL);
testassert(names);
testassert(classInNameList(names, "NotMissingRoot"));
testassert(classInNameList(names, "NotMissingSuper"));
if (weakMissing) {
testassert(! classInNameList(names, "MissingRoot"));
testassert(! classInNameList(names, "MissingSuper"));
} else {
testassert(classInNameList(names, "MissingRoot"));
testassert(classInNameList(names, "MissingSuper"));
}
free(names);
源代码是非官方的,但来自Apple。所以我决定使用这段代码,直到找到更好的方法。