2012-07-01 11 views
48

確かに、順序付き集合はより具体的な集合の集合であるため、なぜではなく、NSOrderedSetNSObjectから継承しますか?NSOrderedSetがNSSetから継承しないのはなぜですか?

+0

developer.apple.comが今ではダウンしていない場合は、今私は好奇心を持っているので、私はドキュメントを見に行くだろう!優れた質問。そして、うまくいけば、アップルのサイトはあまりにも長く続くのではないでしょうか? – WendiKidd

+2

(免責:これは純粋な推測であり、答えとして実際に提供したいとは私にはあまりにも説得力がありませんが...)NSOrderedSetは、NSSetとNSArrayの両方のより具体的なケースです。これらはどちらもプロトコルではなく、Objective-Cに多重継承はありません。だから、あなたはどちらを選ぶのですか?名前のためにNSSetの引数がありますが、それは完全にNSUniqueArrayだったでしょうか?それを安全にして、両者を捨てなさい... –

+1

私はあなたが言っていることを正確に見ていますが、あなたはそれが納得のいくものではないことは間違いありません。私は直感的に '' [aSet intersectsSet:anOrderedSet] 'が可能であることを期待しています(しかし' NSOrderedSet'は 'NSSet'のサブクラスではないので)' NSSet'はスーパークラスに対して ' NSArray' - そしてそれらが等しく論理的な選択肢を作ったとしても、多形性を失うことは、どちらにせよ劣位の選択肢を選択しない。 – jhabbott

答えて

72

私はNSSetのインターフェイスを経由しました。あなたは正しいです、注文セットはLiskov substitution principleを満足するように見え、そのためNSSetから継承することができます。

これを破る少しの方法があります:mutableCopymutableCopyの戻り値はNSMutableSetである必要がありますが、NSMutableOrderedSetNSOrderedSetから継承する必要があります。両方を持つことはできません。

いくつかのコードで説明しましょう。まずは、NSSetNSMutableSetの正しい動作を見てみましょう:

NSSet* immutable = [NSSet set]; 
NSMutableSet* mutable = [immutable mutableCopy]; 

[mutable isKindOfClass:[NSSet class]]; // YES 
[mutable isKindOfClass:[NSMutableSet class]]; // YES 

、のはNSSetからNSOrderedSet継承をふりましょう、とNSOrderedSetからNSMutableOrderedSet継承:

//Example 1 
NSOrderedSet* immutable = [NSOrderedSet orderedSet]; 
NSMutableOrderedSet* mutable = [immutable mutableCopy]; 

[mutable isKindOfClass:[NSSet class]]; // YES 
[mutable isKindOfClass:[NSMutableSet class]]; // NO (this is the problem) 

NSMutableOrderedSetではなくNSMutableSetから継承された場合はどう?

//Example 2 
NSOrderedSet* immutable = [NSOrderedSet orderedSet]; 
NSMutableOrderedSet* mutable = [immutable mutableCopy]; 

[mutable isKindOfClass:[NSSet class]]; // YES 
[mutable isKindOfClass:[NSMutableSet class]]; // YES 
[mutable isKindOfClass:[NSOrderedSet class]]; // NO (this is a problem) 

は、実施例1では、あなたは振る舞いが異なるためNSSetを期待関数にNSOrderedSetを渡すことができないだろう。その後、我々は別の問題を取得します。基本的には、下位互換性の問題です。

例2では、​​NSMutableOrderedSetは、NSOrderedSetを期待する関数に渡すことができません。後者から継承しないためです。

NSMutableOrderedSetは、Objective-Cに多重継承がないため、NSMutableSetNSOrderedSetの両方を継承できないためです。これを回避する方法は、が両方のプロトコルを実装できるので、NSMutableSetNSOrderedSetのプロトコルを作ることです。 Appleの開発者は、余分なプロトコルがなくても簡単だったと思う。

+0

私はプロトコルがもっと理にかなっていると思います。NSMutableSetがすでに定義されていて、すでに変更可能性のためのプロトコルを使用していないという事実ともっと関係があります。'NSMutableSet'が既にそれに従っているにもかかわらず、プロトコルはまだ追加できませんでしたか? – jhabbott

+0

彼らが望むなら、何も壊すことなく新しいプロトコルを追加することができます。将来的に追加されるかもしれません。 –

+2

偉大な答え、これはNSHipsterの本で使用されました。これは私がこの質問を見つけた方法です... NSHipsterの本がこの問題をクラスクラスタであるNSSetに直接リンクする理由を知っていますか?これは変更可能なコピーの問題とは異なる具体的なクラスですが、あなたは知っていますか? http://nshipster.com/nsorderedset/ –

関連する問題