Objective-C检测类是否覆盖继承的方法

时间:2013-06-17 12:12:05

标签: objective-c inheritance override

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

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

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

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

2 个答案:

答案 0 :(得分:17)

测试非常简单:

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对选择器的实现与其超类有不同”,这可能(或许更具体地说)是你所要求的。

答案 1 :(得分:11)

在您的基类中:

BOOL isMethodXOverridden = [self methodForSelector:@selector(methodX)] !=
                           [BaseClass instanceMethodForSelector:@selector(methodX)];
如果你的子类覆盖了methodX,

会给你YES。

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