在Obj-C中发现给定类的子类

时间:2009-11-27 21:04:35

标签: objective-c cocoa reflection

有没有办法在运行时发现给定类中存在哪些子类?

编辑:到目前为止,从答案来看,我想我需要澄清一下我想要做的事情。我知道这在Cocoa中并不常见,并且可能会有一些警告。

我正在使用动态创建模式编写解析器。 (参见Buck and Yacktman撰写的Cocoa Design Patterns一书,第5章。)基本上,解析器实例处理堆栈,并实例化知道如何执行某些计算的对象。

如果我可以获得MYCommand类的所有子类,我可以为用户提供可用命令列表。此外,在第5章的示例中,解析器具有替换字典,因此可以使用+, - ,*和/等运算符。 (它们被映射到MYAddCommand等等。)对我来说,似乎这些信息属于MyCommand子类,而不是解析器实例,因为它有点挫败了动态创建的想法。

5 个答案:

答案 0 :(得分:19)

不直接,不。但是,您可以获取在运行时注册的所有类的列表,并查询这些类的直接超类。请记住,这不允许您在继承树中找到该类的所有祖先,只是直接超类。

您可以使用objc_getClassList()来获取向运行时注册的Class个对象的列表。然后,您可以遍历该数组并在这些[NSObject superclass]对象上调用Class以获取其超类“Class对象。如果由于某种原因,您的课程不使用NSObject作为其根类,则可以改为使用class_getSuperclass()

我还应该提一下,如果您认为有必要进行此类发现,那么可能会错误地考虑您的应用程序的设计。很可能还有另一种更常规的方法来完成你想要实现的目标,而不涉及对Objective-C运行时的内省。

答案 1 :(得分:13)

不是试图自动注册MYCommand的所有子类,为什么不将问题分成两部分呢?

首先,提供用于注册类的API,例如+[MYCommand registerClass:]

然后,在MYCommand中创建代码,这意味着任何子类都会自动注册。类似的东西:

@implementation MYCommand
+ (void)load
{
    [MYCommand registerClass:self];
}
@end

答案 2 :(得分:4)

Marc和bbum打了钱。这通常不是一个好主意。

但是,我们在CocoaHeads wiki上有代码执行此操作:http://cocoaheads.byu.edu/wiki/getting-all-subclasses

答案 3 :(得分:3)

另一种方法刚刚由Matt Gallagher在his blog上发表。

答案 4 :(得分:0)

我的运行时浏览器项目here中的代码包含-subclassNamesForClass:方法。请参阅RuntimeReporter.[hm]文件。