Re: Getting all subclasses
Re: Getting all subclasses
- Subject: Re: Getting all subclasses
- From: Christopher Nebel <email@hidden>
- Date: Wed, 18 Jun 2008 13:56:08 -0700
That depends on what you mean by "automatically". If you read the
documentation, you'll see this bit:
"The load message is sent to classes and categories that are both
dynamically loaded and statically linked, but only if the newly loaded
class or category implements a method that can respond."
So, the method will be called "automatically" upon load, but only if
each subclass implements its own +load implementation, which probably
is more trouble than you want. Also, there's no guarantee about the
order +load calls are issued, so a subclass's +load might get called
before its superclass's, and +load is considered bad performance juju,
since it makes the system do work regardless of whether or not the
application uses the class. +initialize doesn't have those problems,
but it does have a different one -- notice the second sentence,
quoting here from the +initialize documentation:
"The runtime sends initialize to each class in a program exactly one
time just before the class, or any class that inherits from it, is
sent its first message from within the program. (Thus the method may
never be invoked if the class is not used.)"
That makes it unsuitable (or at least kind of risky) for the find-all-
the-subclasses task originally described. objc_getClassList really is
the right approach, though I'll note that caching the result doesn't
work if new classes get loaded dynamically.
--Chris N.
On Jun 18, 2008, at 10:24 AM, Jean-Daniel Dupas wrote:
IIRC, +initialize call the super implementation if the child class
does not override it, but not the +load method that is called
exactly once per class and per categorie.
So +load will not be called automatically.
Le 18 juin 08 à 18:57, Mike Abdullah a écrit :
Another option would be to write a +load method in your abstract
superclass that will be automatically called for any subclasses and
register them with the superclass.
Mike.
On 18 Jun 2008, at 16:45, Laurent Cerveau wrote:
Fantastic!
Thanks to you and Omar.
laurent
On Jun 18, 2008, at 9:28 AM, Graham Cox wrote:
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 (email@hidden)
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:
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden