检查子类是否覆盖一个方法

是否有可能检查一个子类是否实现了一个方法,该方法存在于其直接的超类或其超类的某个超类中?

例如,我UIView ,使我的应用程序的自定义通用视图,然后我inheritance这个自定义视图。 现在我的一些子类重写UIView一些方法,有些则不。 我只想调用这个方法,如果它实际上被覆盖,我不想调用默认的UIView方法。

有没有办法来检查这一点,即与类似于respondsToSelector:的方法respondsToSelector:

编辑:这个问题是不同于在Objective-C中检测到的问题,如果类重写inheritance的方法,因为我不知道或不想关心哪个超类最初实现的方法。

基于Mert Buran的这个答案 。

您可以创build一个简单的方法来检查给定的对象是否覆盖给定的select器(方法):

 -(BOOL)checkIfObject:(id)object overridesSelector:(SEL)selector { Class objSuperClass = [object superclass]; BOOL isMethodOverridden = NO; while (objSuperClass != Nil) { isMethodOverridden = [object methodForSelector: selector] != [objSuperClass instanceMethodForSelector: selector]; if (isMethodOverridden) { break; } objSuperClass = [objSuperClass superclass]; } return isMethodOverridden; } 

这可以被称为如下:

 [self checkIfObject:someObject overridesSelector:@selector(someSelector)]; 

不幸的是,没有相当于respondsToSelector:这将为你做这个工作。 正如你可能知道的那样,只要类本身或者它的任何一个超类实现了这个方法, respondsToSelector:就会返回YES

但是为什么不把这个方法的一个空实现放到你的自定义子类中,这样你就可以确保调用它没有任何作用,并且不会在超类中调用相同的方法。 你有没有想过这个?

更新:尽pipe没有与respondsToSelector:等效的方法,但您可能需要查看Objective-C运行时 。 它是一个库,允许您运行时检查类的特征(有点类似于Javareflection)。 看看这里的参考。

不是最佳的解决scheme,但你可以保留一个布尔成员到你的UIView子类(让我们称之为UIViewSub指示是否所需的行为是由类实现的,并在使用该方法之前检查该布尔值。

你的子类(那些inheritanceUIViewSub )将在其构造中相应地设置/取消设置该成员(即,如果它确实覆盖了它的实现)

扩展ZeMoon的答案,我发现没有足够的逻辑来满足所有的情况。 我需要添加一个检查来确保循环中下一个超类的实例完全实现指定的select器。 UIView子类就是一个例子。

 while (objSuperClass != Nil) { isMethodOverridden = ([objSuperClass instancesRespondToSelector:selector]) && ([object methodForSelector:selector] != [objSuperClass instanceMethodForSelector:selector]); if (isMethodOverridden) { } } 

使用运行时,您需要使用函数Method

 * class_copyMethodList ( Class cls, unsigned int *outCount ); 

这会给你一个清单来处理。