在Objective-C中,如果有任何子类实现,有一种方法可以询问一个类。
我有一个Base类,它有多个子类。我想循环遍历所有子类并在每个子类上执行类选择器。
修改:
我有一组可以处理某些类型数据的类。每个处理器都是一个基类,它提供了每个处理器所需的方法。
每个类都知道它可以处理哪些数据,而某些类可以比其他类更好地处理某些类型的数据。
我想在每个类上都有一个类方法,它会向工厂类提供一个响应,表示我可以处理该数据,并指出它可以处理它的程度。
然后,工厂将根据哪个类说它可以最好地处理数据来决定实例化哪个类。
我也从2009年发现了这个问题(我在发布之前进行了搜索,但没有发现任何内容)Discover subclasses of a given class in Obj-C。
编辑2 :
+ (void)load
方法看起来是我正在寻找的完美解决方案。所以我现在有以下内容:
+ (void)registerSubclass:(Class)subclass {
NSLog(@"Registered %@", subclass);
}
在我的基类中,这是我的潜艇。
+(void)load {
[BaseSwitch registerSubclass:[self class]];
}
现在显示每个子类的调试消息。
我的下一个问题是(可能是一个愚蠢的问题),如何存储在registerSubclass方法中注册的类。有没有办法让我可以在以后阅读的类变量?
编辑3 :
在这里找到一些示例代码A simple, extensible HTTP server in Cocoa
这给我留下了以下内容,毕竟说完了之后看起来很简单。但我想我会把它放在这里供将来参考。
@implementation BaseSwitch
static NSMutableArray *registeredSubclasses;
+ (void)registerSubclass:(Class)subclass {
if (registeredSubclasses == nil) {
registeredSubclasses = [[NSMutableArray alloc] init];
}
[registeredSubclasses addObject:subclass];
NSLog(@"Registered %@", subclass);
}
+ (void)logSubclasses {
for (int i = 0; i < [registeredSubclasses count]; i++) {
NSLog(@"%@", [registeredSubclasses objectAtIndex:i]);
}
}
@end
感谢大家的建议,如果出现其他问题,我会在几天之后再回答这个问题。
答案 0 :(得分:10)
此函数为您提供类的所有子类:
#import <objc/runtime.h>
NSArray *ClassGetSubclasses(Class parentClass)
{
int numClasses = objc_getClassList(NULL, 0);
Class *classes = NULL;
classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * numClasses);
numClasses = objc_getClassList(classes, numClasses);
NSMutableArray *result = [NSMutableArray array];
for (NSInteger i = 0; i < numClasses; i++)
{
Class superClass = classes[i];
do
{
superClass = class_getSuperclass(superClass);
} while(superClass && superClass != parentClass);
if (superClass == nil)
{
continue;
}
[result addObject:classes[i]];
}
free(classes);
return result;
}
答案 1 :(得分:-7)
您永远不能列出类的子类。 (几乎)任何编程语言。这是面向对象编程的基本属性之一。
考虑更改对象模型。
您可能想要的是创建一个抽象类和不同的子类,但不应该从抽象类访问子类。您应该创建另一个对象(Factory类),该对象注册子类并在需要时选择适当的对象。
请注意,您无法从类本身有效地注册类。对于要执行的类代码,必须首先加载该类。这意味着,您必须在其他类中导入其标头,这意味着您实际上是通过导入其标头来注册该类。 有两种可能的解决方案: