【问题标题】:Finding classes that declare that they conform to a specific protocol using the Objective-C runtime使用 Objective-C 运行时查找声明它们符合特定协议的类
【发布时间】:2011-06-18 13:20:52
【问题描述】:

我正在尝试找出一种“标记”类的方法,这些类将在稍后编写,以便我可以在运行时找到它们,但不强制使用特定的父类。目前我正在考虑应用一个协议,然后找到所有具有该协议的类。

但我无法弄清楚如何。

有谁知道是否有可能找到在运行时实现特定协议的所有类?或者 - 有没有更好的方法来“标记”类并找到它们?

【问题讨论】:

  • Aroth 的回答会奏效,但我建议您重新审视您的架构并消除做这种事情的需要。一般来说,这种松散耦合的架构将导致未来的代码非常脆弱,并且会导致严重的维护/重构问题。有趣,当然,但最终不切实际。
  • 通常我会,但我正在玩的是类似于 springframework 概念的东西。实际上,我正在编写代码以对在我的框架包含在另一个项目中之前不存在的类进行操作。我正在尝试做的是允许开发人员利用我正在做的事情而不需要扩展我的类,如果它们有自己的层次结构可能会证明是有问题的。因此,我正在寻找“标记”类的方法,以便我的框架知道如何使用它们。
  • 酷。我建议您提供一些抽象基类,并让其他开发人员从中继承,并根据需要覆盖功能。同样,让开发人员在您的框架中有效地注册他们的类也很有用;这使他们有机会根据配置有条件地注册某些类而不是其他类。
  • 昨晚我在玩一个预处理器定义,它可以放在一个类中并生成一个新的方法实现。这使开发人员可以使用等效的 Java 注释来标记特定方法。然后我可以让我的软件扫描运行时并找到定义添加的所有其他方法并执行它们以进行注册。因此,开发人员所要做的就是放入一行代码。我不想做一个抽象基类,因为开发人员可能已经有一个,我不想限制它们。到目前为止,唯一的限制是我的 C 知识。 :-(

标签: objective-c runtime


【解决方案1】:

使用Objective-C Runtime API 看起来应该不会太难。具体来说,您似乎可以使用objc_getClassListclass_conformsToProtocol 执行以下操作:

Class* classes = NULL;
int numClasses = objc_getClassList(NULL, 0);
if (numClasses > 0 ) {
    classes = malloc(sizeof(Class) * numClasses);
    numClasses = objc_getClassList(classes, numClasses);
    for (int index = 0; index < numClasses; index++) {
        Class nextClass = classes[index];
        if (class_conformsToProtocol(nextClass, @protocol(MyTaggingProtocol))) {
            //found a tagged class, add it to the result-set, etc.
        }
    }
    free(classes);
}

【讨论】:

  • 我想我可能不得不这样做。但是希望有更好的方法,因为似乎有成千上万的课程。虽然我只打算做一次,所以性能并不那么重要。谢谢
  • @Derek - 是的,我很确定您必须迭代所有内容。大多数反射语言并没有提供内置的“给我所有实现 X 的已知类”类型的查询。但除非您尝试做一些非常精细的事情,否则执行一次迭代并缓存结果就足够了。
  • 在 ARC 下然后参考:stackoverflow.com/questions/8730697/…
【解决方案2】:

我认为您必须遍历类列表 (objc_getClassList()) 并检查每个类是否实现相关协议 (class_conformsToProtocol())。

【讨论】:

    【解决方案3】:

    以防万一有人对这个老问题感兴趣,我最终编写了一些代码来定位应用程序的所有捆绑包并扫描这些捆绑包中的类。这比使用基于objc_getClassList 的代码要高效得多,因为它扫描了有限数量的类,而不是整个运行时。

    如果您有兴趣,可以在这里找到我使用的代码:https://github.com/drekka/Alchemic/blob/master/alchemic/NSBundle%2BAlchemic.m

    【讨论】:

    • 您介意分享您为此编写的代码吗?
    • 添加了我评论的链接
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    • 2015-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多