NSObject isEqual とは:ハッシュのデフォルト関数は?
-
12-09-2019 - |
質問
私はデータベースモデルクラスを持っています。 NSObject
. 。これらのオブジェクトのセットを NSMutableArray
. 。私が使う indexOfObject:
一致するものを見つけるために。問題は、モデル オブジェクトのメモリ アドレスが変更されることです。だから私はオーバーライドしています hash
メソッドを使用してモデルの行 ID を返します。ただし、これでは問題は解決しません。また、オーバーライドする必要があります isEqual:
の値を比較するメソッド hash
方法。
は何ですか isEqual:
デフォルトで等しいかどうかを判断するために使用するメソッドは?
メモリアドレスを使用していると思います。を読んだ後、 isEqual:
ドキュメントの値を使用していると思いました hash
方法。その値をオーバーライドしようとしても最初の問題は解決しなかったため、明らかにそうではありません。
解決
ご想像のとおり、 NSObject
のデフォルト isEqual:
動作はオブジェクトのメモリ アドレスを比較します。奇妙なことに、これは現在文書化されていません。 NSObject クラスリファレンス, 、しかし、それはに文書化されています 内観 ドキュメントには次のように記載されています。
デフォルト
NSObject
の実装isEqual:
単にポインタが等しいかどうかをチェックします。
もちろん、ご存知のとおり、次のサブクラスは NSObject
上書きできる isEqual:
違う行動をすること。例えば、 NSString
さんの isEqual:
メソッドが渡されたとき、別のメソッドが渡される NSString
, 、最初にアドレスをチェックし、次に文字列間のリテラルの正確な一致をチェックします。
他のヒント
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 hash
にはプロパティではありません方法となりましたが、それはあります。
私はNSObject
のisEquals
が==
演算子を使用していることを前提となり、そしてhash
はメモリアドレスを使用します。
isEquals
方法は、平等のための絶対的なテストとしてhash
を使用してはいけません。 (単なる以上2 ^ 32の異なるオブジェクトを作成し、そのうちの少なくとも2つが同じhashCode
を持つことになります)あなたは十分なオブジェクトを検索した場合、同様のhash
を持つ2つのオブジェクトを持つことが保証されます。
言い換えれば、hash
は、以下の仕様を必要とする:2つのオブジェクトが等しい場合は、次にそれらのhash
は等しくする必要があります。二つのオブジェクトhash
値に等しいである場合は、それらは必ずしも等しくない。
ヒントとして、あなたは常に一緒isEquals
とhashCode
をオーバーライドする必要があります。