クラスがキーとして適切であり、期待どおりに機能するかどうかを判断する方法はありますか?たとえば、 NSDictionaryでNSIndexPathをキーとして使用したいのですが、同じ整数を持つ2つの異なるNSIndexPathインスタンスかどうかはわかりません。値は常に同じハッシュ値を返します。
3 に答える
AppleのNSObjectのisEqualドキュメントには次のように書かれています。
2つのオブジェクトが等しい場合、それらは同じハッシュ値を持っている必要があります。この最後の点は、サブクラスでisEqual:を定義し、そのサブクラスのインスタンスをコレクションに入れる場合に特に重要です。サブクラスでもハッシュを定義していることを確認してください。
次のコードを見てください。
NSIndexPath *indexPath1 = [NSIndexPath indexPathForRow:0 inSection:0];
NSIndexPath *indexPath2 = [NSIndexPath indexPathForRow:0 inSection:0];
NSObject *obj1 = [[NSObject alloc] init];
NSObject *obj2 = [[NSObject alloc] init];
NSLog(@"NSIndexPath isEqual's Result: %d", [indexPath1 isEqual:indexPath2]);
NSLog(@"NSObject isEqual's Result: %d", [obj1 isEqual:obj2]);
出力結果:
NSIndexPath isEqualの結果:1
NSObject isEqualの結果:0
NSObject isEqualの実装は 、2つのオブジェクトのアドレスを比較することであり、ハッシュの実装は、オブジェクトのアドレスを返すことです。
NSIndexPathはNSObjectから継承され、NSIndexPath isEqual出力結果によると、NSIndexPathのisEqual実装はスーパークラスのisEqualメソッドをオーバーライドする必要があり、NSIndexPathもスーパークラスのハッシュメソッドをオーバーライドします。
ちなみに、NSIndexPathはNSCopyingプロトコルにも準拠しています。
したがって、NSIndexPathはNSDictionaryのKeyクラスとして使用できます。
オブジェクトがキーとしてどのように動作するかは、isEqual:を実装する方法によって異なります。これにより、2つのキーが衝突するかどうかが決まります。
たとえば、パスに同じインデックスのセットがある場合、インデックスパスは等しい(したがって衝突します)。したがって、同じパスを記述する2つの異なるオブジェクトは、辞書では同じキーとして認識されます...おそらくそれがどのようになりたいか。
NSDictionaryキーには、次の3つの要件があります。
- NSCopyingプロトコルをサポートする
- 合理的なハッシュ法
- isEqual
NSIndexPathは問題ないはずです。