6

クラスChildはParentを拡張します。親は、を含むオプションのメソッドを持つプロトコルCを実装します-(void)d。子には-d;の実装があります。呼び出す必要があり[super d]ますか?

言い換えれば、[super d]何かがそれに応答する場合にのみ呼び出すために、どのコードを書くのですか?親の実装を制御していないと仮定します。いつでも変更される可能性があります。

これが私が考えたすべての方法です。私は現在4番を使用しています。

どうやら賢明な答え1:

[super d]; // Delete this line if a runtime exception occurs when you try it

親が-dを動的に実装する可能性があるため、これは機能しません。これは、フィールドではなくテストするときに機能します。または、Parentの実装が変更されて、このテストの結果が正しくなくなる可能性があります。

どうやら賢明な答え2:

if ([super respondsToSelector:_cmd])
    [super d];

NSObjectの-respondsToSelectorの実装は、Childで実装を検出し、すべての場合にYESを返すため、これは機能しません。

どうやら賢明な答え3:

if ([[self superclass] instancesRespondToSelector:_cmd])
    [super d];

これは、スーパークラスが常に-dを実装していることを知っている場合にのみ機能します。インスタンスがこのメソッドが存在するかどうかを動的に判断する場合、この手法は機能しません。実行時にParentの実装に対する静的な変更を取得するという点で1よりも優れています。

どうやら賢明な答え4:

@try
{
    [super d];
}
@catch (NSException *exception)
{
    NSString *templateReason = [NSString stringWithFormat:
                                @"-[%@ %@]: unrecognized selector sent to instance %p"
                                ,NSStringFromClass([self superclass])
                                ,NSStringFromSelector(_cmd)
                                ,self];
    if (![exception.reason isEqualToString:templateReason])
        @throw exception;
}

templateReasonを計算し、それを例外理由と比較するのはコストがかかるため、スーパークラスのメソッドが存在しない場合、このパフォーマンスは低下します。

この場合の例外理由文字列の形式は、将来のSDKまたはランタイムリリースで変更される可能性があるため、このメカニズムは脆弱です。

4

3 に答える 3

5

これらのことはどれも必要ありません。

あるクラスまたは他のクラスをサブクラス化する場合は、動作を置き換えているのか補足しているのかをすでに知っている必要があります。

つまり、実装が存在し、それを別の方法で実行したい場合は、superを呼び出さないでください。

実装が存在しない場合は、superを呼び出さないでください。

実装存在するが、それを補足したい場合は、superを呼び出します。

補遺:

実装がいつでも変更できるかどうかは、あなたの質問には関係ありません。重要なのは、インターフェースが変更されたかどうかです。

インターフェイスが絶えず変化している場合、そのクラスはサブクラス化、または使用すら非常に貧弱な候補である可能性が高くなります。

于 2011-11-23T13:58:20.107 に答える
1

残念ながら、私はこれらの答えのいずれかが良いかどうかではありません。残念ながら、これは目的に帰着します。スーパークラスメソッドを呼び出すことを意図していない場合もあります。メソッドのオーバーライドは、スーパークラスの機能の上に機能をチェーンするのではなく、メソッドを置き換えることである場合があります。

それは、ドキュメントを読み、適切なアプローチを選択することです。

これが実装しているフレームワークに関するものであり、一貫したアプローチを使用したい場合は、2または3で十分です。1と4は例外に依存しています。これは、Objective-cの真に例外的な問題を除いて実際に使用することを意図したものではありません。

于 2011-11-23T13:57:32.500 に答える
-1

Objective cでは、プロトコルのメソッドを必須またはオプションとして定義できますが、プロトコルに準拠しているクラスが実際にそのプロトコルを実装しているかどうかはわかりません。

したがって、インスタンスがプロトコルに応答するかどうかを常に確認する必要があります。
オプション2を選択しますが、これが最もエレガントです。将来、プロトコルメソッドをオプションにする場合でも、これが正しい解決策になります。

オプション4私は個人的に多くのJavaっぽいものを見つけます。

于 2011-11-23T13:59:49.543 に答える