If you need a list of subclasses of a class, there isn't a built-in function - you have to test them one at a time. However I had the exact same need recently and wrote a little helper class to do it. One thing I ran into in my situation is that I really needed to prevent +initialize from ever getting called, because some low-level classes in the Cocoa framework wrote certain messages to the log when they were invoked (because they are obsolete and shouldn't be used) but testing for the class itself was enough to trigger this.

So, my code uses a lower-level function. Here it is:




@interface DKRuntimeHelper : NSObject

+ (NSArray*)    allClasses;
+ (NSArray*)    allClassesOfKind:(Class) aClass;


@end



@implementation DKRuntimeHelper


+ (NSArray*)    allClasses
{
        return [self allClassesOfKind:[NSObject class]];
}


+ (NSArray*)    allClassesOfKind:(Class) aClass
{
// returns a list of all Class objects that are of kind <aClass> or a subclass of it currently registered in the runtime. This caches the // result so that the relatively expensive run-through is only performed the first time
        
        static NSMutableDictionary* cache = nil;
        
        if ( cache == nil )
                cache = [[NSMutableDictionary alloc] init];
                
        // is the list already cached?
        
        NSArray* cachedList = [cache objectForKey:NSStringFromClass( aClass )];
        
        if ( cachedList != nil )
                return cachedList;
                
        // if here, list wasn't in the cache, so build it the hard way
        
        NSMutableArray* list = [NSMutableArray array];

        Class*                  buffer = NULL;
        Class                   cl;
        
        int i, numClasses = objc_getClassList( NULL, 0 );
        
        if( numClasses > 0 )
        {
                buffer = malloc( sizeof(Class) * numClasses );
                
                NSAssert( buffer != nil, @"couldn't allocate the buffer");
                
                (void)  objc_getClassList( buffer, numClasses );
                
// go through the list and carefully check whether the class can respond to isSubclassOfClass: - if so, add it to the list.
                
                for( i = 0; i < numClasses; ++i )
                {
                        cl = buffer[i];
                        
                        if( classIsSubclassOfClass( cl, aClass ))
                                [list addObject:cl];
                }
                
                free( buffer );
        }
        
        // save in cache for next time
        
        [cache setObject:list forKey:NSStringFromClass( aClass )];
        
        return list;
}

@end



BOOL    classIsNSObject( const Class aClass )
{
// returns YES if <aClass> is an NSObject derivative, otherwise NO. It does this without invoking any methods on the class being tested.
        
        return classIsSubclassOfClass( aClass, [NSObject class]);
}


BOOL    classIsSubclassOfClass( const Class aClass, const Class subclass )
{
        Class   temp = aClass;
        int             match = -1;

while(( 0 != ( match = strncmp( temp->name, subclass->name, strlen( subclass->name )))) && ( NULL != temp->super_class ))
                temp = temp->super_class;

        return ( match == 0 );
}




hth,


cheers, Graham




On 18 Jun 2008, at 3:19 pm, Laurent Cerveau wrote:

Hi

Is there a way to get all subclases of a class. I have a class that I would call abstract (although I did not find any real way to declare some methods as virtual) and would like to get a list of all "real" subclass implementations.

Thanks

laurent
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/graham.cox%40bigpond.com

This email sent to [EMAIL PROTECTED]

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to