2016-05-14 6 views
1

のObjective-CNSDictionaryのキーにSKNodeオブジェクトを使用していますか? (問題の比較)

このコードを考えてみましょう:

SKNode *n1 = [SKNode new]; 
SKNode *n2 = [SKNode new]; 

NSMutableDictionary *d = [NSMutableDictionary new]; 

[d setObject:@"A" forKey:n1]; 
[d setObject:@"B" forKey:n2]; 


if ([d objectForKey:n1]) { 
    NSLog(@"true"); 
} 

私はNSDictionaryの中にキーとしてSKNodeを使用しています。 SKNodeがキーとして存在するかどうかをテストする必要があります。上記の結果は "true"を返さない(または印刷する)わけではないので、テストのための一般的なアプローチは機能していないようです。次のコードもありません。

if ([d allKeys] containsObject:n1]) { 
    NSLog(@"true"); 
} 

私はキーストリングを作成します。すなわち、「キー1」、「キー2」、「真」が印刷される。

このようにテストできますか?

答えて

3

(私がコメントとして書きましたが、実際の質問への答えだったことを私に発生しました。)(NSCopyingプロトコルから-copyを使用して)

NSDictionaryのコピーそのキーを。 SKNodeはNSCopyingに準拠しますが、ノードをコピーすると、古いものに等しくない新しいノードを返します。

SKNode *a = [SKNode new]; 
SKNode *b = [a copy]; 

[a isEqual:b]; // NO
let a = SKNode() 
let b = a.copy() as! SKNode 

a == b // false

だから、辞書のキーとしてSKNodesを使用しても安全ではありません。回避策として、おそらくノードのnameをキーとして使用することができます(ノードの名前が一意である場合)。キーをコピーしないNSMapTableを使用することもできます。

+1

私はちょうど(目的cの)同じ実験をしましたが、私はその結果の説明がないので、答えるのをためらった。一般的に '[[オブジェクトコピー] isEqual:object] == YES'のようなケースではないでしょうか?そのため、NSCopyingに準拠すれば辞書キーで十分です。 – danh

+1

それが真実であればわかりやすくなりますが、ほとんどの場合それが真実だと思いますが、NSCopyingの非公式の要件ではありません。それはあなたがノードを複製することを可能にするために 'copy()'を実装することを選択したようで、新しいノードが古いものと等しくないことを念頭に置いてください。 – jtbandes

+0

NSMapTableが機能しているようです。 –

1

コードは機能するはずです。だから、SKNodeのhashcodeとisEqual:メソッドの実装で何かが間違っている可能性があります。

2つのキーのハッシュコードを記録し、isEqual:何が返ってきたかを確認し、辞書とすべてのキーを記録して、予期せぬことを確認します。

PS。それは正しい答えです正確に jtbandesを回します。もちろん、私のアドバイスに従って、すべてのキーを記録すれば、すべてのキーのキーは予想通りではなく、答えを見つけ出す闘いのチャンスがあることが分かりました。そのように

あなたは些細なハッシュコードメソッドとisEqualでクラスを持っている場合は、単にハッシュコードとしてポインタを取るメソッドとisEqualのためのポインタを比較し、いずれかあなたはコピーで新しいオブジェクトを作成し、辞書が動作しませんクラスを持って、または、コピーが元のオブジェクトを返すクラスがあり、正常に動作します。

+1

新しいオブジェクトを作成する 'copy'は、そのオブジェクトを辞書キーとして使用することで不適格ではありません。コピーでallocを行うのは典型的なことです。新しいオブジェクトと元のオブジェクトが衝突するハッシュを生成し、一緒にisEqual == trueと答えるのが典型的で望ましくあります。 – danh

関連する問題