2011-07-14 5 views
10

それを安全に保つAppleがthis to sayがあります:ルートクラスのカテゴリ -

カテゴリー

は、カテゴリは、ルートクラスを含め、任意のクラスにメソッドを追加することができます。 NSObjectに追加されたメソッドは、コードにリンクされているすべてのクラスで使用できるようになります。カテゴリを持つルートクラスにメソッドを追加することは時々役に立ちますが、非常に危険です。カテゴリに加えられた変更がよく理解され、影響が限定されているように見えるかもしれませんが、継承はそれらに広い範囲を与えます。アプリケーションの見えないクラスに意図しない変更が加えられている可能性があります。あなたがしていることのすべての結果を知ることはできません。さらに、変更を認識していないアプリケーションで作業している他の人は、自分が行っていることを理解できません。

私の質問は、私が十分に奇妙なメソッド名を選んでも、他の誰もそれらを(Appleか自分のプロジェクトで)使用することはないと確信しています。それでも予期しない動作が起こる可能性はありますか?パフォーマンスの影響?

+5

Objective-Cはあなたのサブクラスを好むでしょう。しかし、それを安全にすることは敗者のためです、そうですか? ;) –

答えて

9

アップルがその名前のメソッドを絶対に追加しないと確信しているのなら、それは安全です。 を確実に実行したい場合は、セレクタ名の前に接頭辞を付けます。例えば、ある時点でAdiumは-setObject:atIndex:メソッドをNSMutableArrayに追加しました(既存のAPIメソッド-replaceObject:atIndexを上回る「化粧品」ラッパー)非常に無意味です...それは内部メソッドと同じ名前を持つことが判明しました。わずかに異なるセマンティクス。これによりクラッシュが発生しましたが、一部のOSでのみ発生しました。もしそれが-AISetObject:atIndex:のような名前になっていたら、それはうまくいっていたでしょう。

カテゴリのパフォーマンスへの影響は最小限です。私はその面について心配しません。

+3

システムだけではありません。カテゴリメソッド ' - [NSDictionary setDoubleValue:forKey:]の1つのクラッシュレポートは、同じ名前のメソッドを実装した入力マネージャと競合していましたが、明らかにオブジェクトがDouble:パラメータとして期待されていました。入力マネージャはiChatにコードを挿入するために使用されていたが、明らかにFoundationカテゴリを含むすべてのアプリケーションに完全なハッキングをロードした。 –

+0

私はAISetObjectがもう "化粧品"ではなかったと思います:-) –

1

メソッド名が何かと矛盾しない場合、それらを使用する人が何をしているのかを知っていれば、何の問題も起こらないはずです。カテゴリは余分なメソッドを追加しますが、ではなく、インスタンス変数がクラスに追加されています。サブクラスはより柔軟で、オブジェクト全体として扱われ、すべてのスーパークラスメソッドとそれ自身のものに応答します。あなたができないか、そうするのが不便でない限り、私はサブクラスを作ると言うでしょう。結局のところ、カテゴリーを使用するようにしました。私は通常、フレームワークを持っているときにカテゴリを使用しています。公的に宣言されたクラスにプライベートメソッドを追加する必要があります。