Objective-Cのカテゴリを使用したメソッドのオーバーライド


87

クラスカテゴリを使用して、カテゴリを使用して既に実装されているメソッドをオーバーライドできますか?このような:

1)独自の方法

-(BOOL) method {
  return true;
}

2)オーバーライドされたメソッド

-(BOOL) method {
  NSLog(@"error?"); 
  return true; 
}

これは機能しますか、それとも違法ですか?

回答:


145

アップルのドキュメントから:

現在、Objective-C言語では、カテゴリを使用して、クラスが継承するメソッドまたはクラスインターフェイスで宣言されたメソッドをオーバーライドすることができますが、そうすることはお勧めしません。カテゴリはサブクラスの代わりにはなりません。カテゴリを使用してメソッドをオーバーライドすることには、いくつかの重大な欠点があります。

  • カテゴリが継承されたメソッドをオーバーライドすると、カテゴリ内のメソッドは通常どおり、へのメッセージを介して継承された実装を呼び出すことができますsuper。ただし、カテゴリがそのカテゴリのクラスに存在するメソッドをオーバーライドする場合、元の実装を呼び出す方法はありません

  • カテゴリは、同じクラスの別のカテゴリで宣言されたメソッドを確実にオーバーライドすることはできません。

    Cocoaクラスの多くはカテゴリを使用して実装されているため、この問題は特に重要です。オーバーライドしようとするフレームワーク定義のメソッド自体がカテゴリに実装されている可能性があるため、どの実装が優先されるかは定義されていません。

  • 一部のカテゴリメソッドが存在すると、すべてのフレームワークで動作が変化する可能性があります。たとえば、windowWillClose:NSObjectのカテゴリでデリゲートメソッドをオーバーライドすると、プログラム内のすべてのウィンドウデリゲートは、カテゴリメソッドを使用して応答します。NSWindowのすべてのインスタンスの動作が変わる可能性があります。フレームワーククラスに追加したカテゴリは、動作に不可解な変化を引き起こし、クラッシュを引き起こす可能性があります。


ありがとうございますが、私はすでにそれを知っています。私の訴訟が合法であるかどうかだけです。私の場合は、ドキュメントとは少し異なります。:)
retix

なぜ違うの?元のメソッドがカテゴリに含まれていない場合は合法であるが、強く非推奨であるとドキュメントは述べています。その後、それを行うことができます...
Beno Bet

1
アドバイスありがとうございます。私はこの言語が苦手です。あなたから新しい情報をもらいました。
retix

1
スーパークラスのCategoryで宣言、実装されているCategoryメソッドをオーバーライドすることは正しいですか?
BergP 2013年

2
リンクが壊れています、これは新しいバージョンですか? developer.apple.com/library/ios/documentation/Cocoa/Conceptual/...
RndmTsk


9

古いドキュメントのリンクは死んでいます。私が見つけた最高の代替品はここにありました:Apple Docs

カテゴリメソッド名の衝突を回避する

カテゴリで宣言されたメソッドは既存のクラスに追加されるため、メソッド名には細心の注意が必要です。

カテゴリで宣言されたメソッドの名前が元のクラスのメソッド、または同じクラス(またはスーパークラス)の別のカテゴリのメソッドと同じである場合、どのメソッド実装が使用されるかについての動作は未定義です。ランタイム。独自のクラスでカテゴリを使用している場合、これは問題になる可能性は低いですが、カテゴリを使用して標準のCocoaまたはCocoa Touchクラスにメソッドを追加するときに問題が発生する可能性があります。

軽いタッチを使用しているのはAppleですが、要点は同じです。予測できない動作は静かなので、災害を招きます。


2

カテゴリを使用して、基本クラスの既存のメソッド(たとえば、Carクラスのドライブメソッド)をオーバーライドすることもできますが、これを行うことはできません。問題は、カテゴリーがフラットな組織構造であることです。Car + Maintenance.mの既存のメソッドをオーバーライドし、その動作を別のカテゴリで再度変更することにした場合、Objective-Cが使用する実装を知る方法はありません。このような状況では、ほとんどの場合サブクラス化の方が適しています。

このチュートリアルから、http://rypress.com/tutorials/objective-c/categories

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.