2013-06-17 7 views
6

親クラスのメソッドをオーバーライドしている場合、子クラス内から動的に検出する方法はありますか?クラスBが動的にのみ-methodRed;が上書きされたことを検出することが可能である場合、私は知りたいのですが、上記の例からObjective-Cがクラスが継承したメソッドをオーバーライドするかどうかを検出します

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

このアプローチと他の可能性との違いは、外観が変更される数多くのカスタムビューがあるためです。オーバーライドされたメソッドを動的に検出してトラックを保持できるのであれば、コードが大幅に少なくなります。

答えて

16

これはテストに非常に簡単です:BがAのメソッドをオーバーライドする場合

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

私が知っているか疑問しなければならないのに便利ですが、あなたが知りたい場合、これはあなたが見つける方法です。

厳密に言えば、上のコードは、Bのセレクタの実装がAのセレクタの実装と異なるかどうかを判断します.A> X> Bのような階層を持つ場合は、 Xはセレクタをオーバーライドしますが、Bが優先クラスではないにもかかわらず、これはAと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は、セレクタの異なる実装を持っていない質問をしますそのスーパークラス "よりも(おそらくもっと具体的に)あなたが求めていたものです。お使いのベースクラス内

+0

更新いただきありがとうございます。私はあなたに別の投票を与えるだろうが、私はすでにあなたに1つを与えた。 – cnotethegr8

+2

このコードを使用している人は、 '#import ' – cnotethegr8

+1

する必要があります。さらに簡単です: 'class_getMethodImplementation()'は上記の2つの連鎖呼び出しを置き換えることができます。詳細はhttps://developer.apple.com/documentation/cocoa/reference/objcruntimerefをご覧ください。 –

11

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

あなたはYES methodXがあなたのサブクラスでオーバーライドされた場合に得られます。

上記の回答も正しいですが、それは良く見えるかもしれません。

関連する問題