有没有办法在运行时发现给定类中存在哪些子类?
编辑:到目前为止,从答案来看,我想我需要澄清一下我想要做的事情。我知道这在Cocoa中并不常见,并且可能会有一些警告。
我正在使用动态创建模式编写解析器。 (参见Buck and Yacktman撰写的Cocoa Design Patterns一书,第5章。)基本上,解析器实例处理堆栈,并实例化知道如何执行某些计算的对象。
如果我可以获得MYCommand
类的所有子类,我可以为用户提供可用命令列表。此外,在第5章的示例中,解析器具有替换字典,因此可以使用+, - ,*和/等运算符。 (它们被映射到MYAddCommand
等等。)对我来说,似乎这些信息属于MyCommand
子类,而不是解析器实例,因为它有点挫败了动态创建的想法。
答案 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]
文件。