【问题标题】:Objective-C detect if class overrides inherited methodObjective-C 检测类是否覆盖继承的方法
【发布时间】:2013-06-17 12:12:05
【问题描述】:

有没有办法从子类中动态检测它是否覆盖了它的父类方法?

Class A {
    - methodRed;
    - methodGreen;
    - methodBlue;
}
Class B inherits A {
    - methodRed;
}

从上面的示例中,我想知道 B 类是否能够动态检测到只有 -methodRed; 被覆盖。

我想知道这种方法与其他一些可能性的原因是因为我有几十个自定义视图将改变那里的外观。如果我可以动态检测被覆盖的方法而不是跟踪,那么代码会少很多。

【问题讨论】:

    标签: objective-c inheritance overriding


    【解决方案1】:

    这很容易测试:

    if (method_getImplementation(class_getInstanceMethod(A, @selector(methodRed))) ==
        method_getImplementation(class_getInstanceMethod(B, @selector(methodRed))))
    {
        // B does not override
    }
    else
    {
        // B overrides
    }
    

    我确实想知道知道 B 是否覆盖 A 上的方法有什么帮助,但如果你想知道,这就是你发现的方法。

    还可能值得注意:严格来说,上面的代码确定 B 上选择器的实现是否与 A 上选择器的实现不同。如果您有像 A > X > B 和 X 这样的层次结构覆盖选择器,这仍然会报告 A 和 B 之间的不同实现,即使 B 不是覆盖类。如果您想具体了解“B 是否覆盖此选择器(不管其他任何内容)”,您会想要这样做:

    if (method_getImplementation(class_getInstanceMethod(B, @selector(methodRed))) ==
        method_getImplementation(class_getInstanceMethod(class_getSuperclass(B), @selector(methodRed))))
    {
        // B does not override
    }
    else
    {
        // B overrides
    }
    

    很明显,这提出了一个问题“B 选择器的实现是否与其超类不同”,这就是您所要求的(也许更具体地)。

    【讨论】:

    • 感谢您的更新,这很好!我会再给你一个赞成票,但我已经给了你一个。
    • 更简单:class_getMethodImplementation() 可以替换上面的两个链式调用,并且在某些情况下可能更快。详情请见developer.apple.com/documentation/cocoa/reference/…
    • C'est vrai。 C'est vrai。
    【解决方案2】:

    在您的基类中:

    BOOL isMethodXOverridden = [self methodForSelector:@selector(methodX)] !=
                               [BaseClass instanceMethodForSelector:@selector(methodX)];
    

    如果你的子类重写了methodX,会给你YES。

    上面的答案也是正确的,但可能看起来更好。

    【讨论】:

      猜你喜欢
      • 2012-11-20
      • 2016-01-25
      • 2012-09-27
      • 1970-01-01
      • 1970-01-01
      • 2014-01-15
      • 1970-01-01
      • 2016-01-24
      • 2015-06-30
      相关资源
      最近更新 更多