Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get list of classes already loaded into memory in specific bundle (or binary)?

It's possible to get list of classes from a bundle via NSBundleDidLoadNotification. But I can't figure out how I can get them from already loaded bundle. (same bundle with code)

I'm trying to get class list of my application bundle. More specifically, the classes only in my application binary.

I looked at objc_getClassList, but it returns ALL classes and it's obviously too heavy for me. I need lightweight method. I found objc_copyClassNamesForImage by googling, but it's not documented, and I don't know how to use it safely. I think I can try to use it conventionally, but I want to find another more safe option before going there.

like image 606
eonil Avatar asked Jul 31 '11 03:07

eonil


2 Answers

Another option would be to iterate through all the classes registered with the runtime and use +[NSBundle bundleForClass:] on each one to figure out which one it came from. You can then sort things into sets based on the result.

Something like this:

@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

Then you can call:

NSLog(@"%@", [[NSBundle mainBundle] definedClasses_dd]);
like image 87
Dave DeLong Avatar answered Oct 18 '22 18:10

Dave DeLong


Try this magic:

- (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;
}
like image 23
malhal Avatar answered Oct 18 '22 18:10

malhal