【问题标题】:Discover subclasses of a given class in Obj-C在 Obj-C 中发现给定类的子类
【发布时间】:2009-11-27 21:04:35
【问题描述】:

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

编辑: 从目前的答案来看,我认为我需要进一步澄清我正在尝试做的事情。我知道这在 Cocoa 中并不常见,并且可能会带来一些警告。

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

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

【问题讨论】:

    标签: objective-c cocoa reflection


    【解决方案1】:

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

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

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

    【讨论】:

    • 我会说得更强烈一些;如果您认为需要在生产代码中执行此操作,那么您很可能做错了。向下看的继承自省极为罕见,这也是运行时不直接支持它的原因。你想做什么?
    • @bbum 我已经添加了我正在尝试做的事情的描述。你还觉得我做的非常非常错误吗?在不寻找子类的情况下,我很难想出另一种方法来做到这一点。
    【解决方案2】:

    与其尝试自动注册MYCommand的所有子类,不如将问题一分为二?

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

    然后,在 MYCommand 中创建代码,这意味着任何子类都会自动注册自己。比如:

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

    【讨论】:

    • 这看起来确实是正确的方法。特别是因为文档提到一个类的 +load 方法在其所有超类的 +load 方法之后被调用。非常感谢其他人也提供了答案,他们的答案也很棒。
    • MyCommand 的子类不会在其超类上调用 +load。 +load 仅在实现它的类中调用。
    • 很惊讶有人纠正我花了这么长时间!我通常同意这里的答案,即自动注册是一个坏主意,应该更多地手动处理。
    【解决方案3】:

    Marc 和 bbum 成功了。这通常不是一个好主意。

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

    【讨论】:

    • 另一个警告;当做这种事情时,你最终会导致类按照它们以前可能从未被初始化过的顺序被初始化。这应该不会导致问题,但有时会因为系统类中的依赖关系可能会在版本之间发生变化......
    • 链接代码的描述中明确表示这种方法不会调用+initialize,虽然我还没有尝试过,但似乎是正确的。
    【解决方案4】:

    Matt Gallagher 刚刚在his blog 上发布了另一种方法。

    【讨论】:

      【解决方案5】:

      在我的运行时浏览器项目here 中有代码,其中包含 -subclassNamesForClass: 方法。查看RuntimeReporter.[hm] 文件。

      【讨论】:

      • 谢谢,这是一个有趣的工具,可以添加到我的腰带上。虽然对于这个特殊情况,我会采用 Mike 的方法。
      • 我注意到@NSResponder 发布的链接已损坏。对于那些寻找遍历类层次结构的方法的人,我编写了一个使用类似方法的Class Hierarchy Logger。如果您需要更深入地了解如何迭代子类层次结构,它可能会很有用。希望对您有所帮助!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多