Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Discover subclasses of a given class in Obj-C

Is there any way to discover at runtime which subclasses exist of a given class?

Edit: From the answers so far I think I need to clarify a bit more what I am trying to do. I am aware that this is not a common practice in Cocoa, and that it may come with some caveats.

I am writing a parser using the dynamic creation pattern. (See the book Cocoa Design Patterns by Buck and Yacktman, chapter 5.) Basically, the parser instance processes a stack, and instantiates objects that know how to perform certain calculations.

If I can get all the subclasses of the MYCommand class, I can, for example, provide the user with a list of available commands. Also, in the example from chapter 5, the parser has an substitution dictionary so operators like +, -, * and / can be used. (They are mapped to MYAddCommand, etc.) To me it seemed this information belonged in the MyCommand subclass, not the parser instance as it kinda defeats the idea of dynamic creation.

like image 926
Johan Kool Avatar asked Nov 27 '09 21:11

Johan Kool


4 Answers

Not directly, no. You can however get a list of all classes registered with the runtime as well as query those classes for their direct superclass. Keep in mind that this doesn't allow you to find all ancestors for the class up the inheritance tree, just the immediate superclass.

You can use objc_getClassList() to get the list of Class objects registered with the runtime. Then you can loop over that array and call [NSObject superclass] on those Class objects to get their superclass' Class object. If for some reason your classes do not use NSObject as their root class, you can use class_getSuperclass() instead.

I should mention as well that you might be thinking about your application's design incorrectly if you feel it is necessary to do this kind of discovery. Most likely there is another, more conventional way to do what you are trying to accomplish that doesn't involve introspecting on the Objective-C runtime.

like image 122
Marc W Avatar answered Nov 18 '22 11:11

Marc W


Rather than try to automatically register all the subclasses of MYCommand, why not split the problem in two?

First, provide API for registering a class, something like +[MYCommand registerClass:].

Then, create code in MYCommand that means any subclasses will automatically register themselves. Something like:

@implementation MYCommand
+ (void)load
{
    [MYCommand registerClass:self];
}
@end
like image 44
Mike Abdullah Avatar answered Nov 18 '22 13:11

Mike Abdullah


Marc and bbum hit it on the money. This is usually not a good idea.

However, we have code on our CocoaHeads wiki that does this: http://cocoaheads.byu.edu/wiki/getting-all-subclasses

like image 4
Dave DeLong Avatar answered Nov 18 '22 13:11

Dave DeLong


Another approach was just published by Matt Gallagher on his blog.

like image 3
Johan Kool Avatar answered Nov 18 '22 11:11

Johan Kool