32

であるデータベースモデルクラスがありますNSObject。にこれらのオブジェクトのセットがありますNSMutableArray。私indexOfObject:はマッチを見つけるために使用します。問題は、モデル オブジェクトのメモリ アドレスの変更です。hashそのため、モデルの行 ID を返すメソッドをオーバーライドしています。ただし、これは修正されません。isEqual:メソッドの値を比較するには、メソッドをオーバーライドする必要もありますhash

isEqual:このメソッドは、既定で等しいかどうかを判断するために何を使用しますか?

メモリアドレスを使用していると思います。ドキュメントを読んだ後、メソッドisEqual:の値を使用していると思いました。hash明らかに、その値をオーバーライドしようとしても最初の問題は解決しなかったため、そうではありません。

4

3 に答える 3

31

ご想像のとおり、NSObjectのデフォルトのisEqual:動作はオブジェクトのメモリアドレスを比較することです。不思議なことに、これは現在NSObjectクラスリファレンスには記載されていませんが、イントロスペクションのドキュメントには次のように記載されています。

のデフォルトのNSObject実装はisEqual:、ポインタが等しいかどうかをチェックするだけです。

もちろん、ご存知のとおり、のサブクラスはNSObjectオーバーライドisEqual:して異なる動作をすることができます。たとえば、NSString'sisEqual:メソッドは、別のメソッドが渡さNSStringれると、最初にアドレスをチェックし、次に文字列間の完全なリテラル一致をチェックします。

于 2010-11-23T06:55:32.197 に答える
12

のデフォルト実装に関する答えisEqual:は包括的なものです。したがって、 のデフォルトの実装に関するメモを追加しますhash。ここにあります:

-(unsigned)hash {return (unsigned)self;}

つまり、 で使用されるのと同じポインタ値ですisEqual:。これを確認する方法は次のとおりです。

NSObject *obj = [[NSObject alloc] init];
NSLog(@"obj: %@",obj);
NSLog(@"hash: %x",obj.hash);

結果は次のようになります。

obj: <NSObject: 0x16d44010>
hash: 16d44010

よろしくお願いします。

iOS 8 の BTW はhashメソッドではなくプロパティになりましたが、そこにあります。

于 2014-10-01T02:43:03.543 に答える
5

演算子をNSObject isEquals使用し、メモリアドレスを使用すると思います。==hash

isEqualsメソッドはhash、等しいかどうかの絶対的なテストとして使用しないでください。十分な数のオブジェクトを検索すると、類似した を持つ 2 つのオブジェクトがあることが保証されhashCodeます (2^32 を超える異なるオブジェクトを作成するだけで、少なくとも 2 つのオブジェクトは同じ になりますhash)。

つまり、hash次の仕様が必要です。2 つのオブジェクトが等しい場合、それらは等しいhash必要があります。ただし、2 つのオブジェクトのhash値が等しい場合、必ずしも等しいとは限りません。

isEqualsヒントとして、常にand を一緒にオーバーライドする必要がありますhashCode

于 2009-08-06T21:48:26.777 に答える