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

Joh*_*ool 9 reflection cocoa objective-c

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

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

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

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

Mar*_*c W 19

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

您可以使用objc_getClassList()获取Class运行时注册的对象列表.然后你可以遍历那个数组并调用[NSObject superclass]那些Class对象来获取它们的超类' Class对象.如果由于某种原因,您的类不用NSObject作其根类,则可以使用class_getSuperclass().

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

  • 我会说得更强烈; 如果你认为你需要在生产代码中这样做,你很可能做错了.向下看的继承内省非常罕见,这也是运行时不直接支持它的原因.你想做什么? (7认同)

Mik*_*lah 13

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

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

然后,在MYCommand中创建代码,这意味着任何子类都会自动注册.就像是:

@implementation MYCommand
+ (void)load
{
    [MYCommand registerClass:self];
}
@end
Run Code Online (Sandbox Code Playgroud)

  • MyCommand的子类不会在其超类上调用+ load.+ load仅在实现它的类中调用. (2认同)