[解決済み】isEqual:とハッシュをオーバーライドするためのベストプラクティス
質問
を正しくオーバーライドするにはどうすればよいのでしょうか?
isEqual:
Objective-Cでは? 2つのオブジェクトが等しい場合、quot;catch" は、(quot;catch" で決定されるように)
isEqual:
メソッド) を使用すると、同じハッシュ値を持つ必要があります。
は
イントロスペクション
のセクションは
Cocoa基礎ガイド
をオーバーライドする例があります。
isEqual:
という名前のクラスに対して、以下のようにコピーされます。
MyWidget
:
- (BOOL)isEqual:(id)other {
if (other == self)
return YES;
if (!other || ![other isKindOfClass:[self class]])
return NO;
return [self isEqualToWidget:other];
}
- (BOOL)isEqualToWidget:(MyWidget *)aWidget {
if (self == aWidget)
return YES;
if (![(id)[self name] isEqual:[aWidget name]])
return NO;
if (![[self data] isEqualToData:[aWidget data]])
return NO;
return YES;
}
ポインタの等質性をチェックし、次にクラスの等質性をチェックし、最後にオブジェクトを
isEqualToWidget:
をチェックするだけです。
name
と
data
プロパティを使用します。 例題の内容
ではありません。
をオーバーライドする方法です。
hash
.
等式に影響しない他のプロパティがあるとします。
age
. を使うべきではありません。
hash
メソッドをオーバーライドして
name
と
data
はハッシュに影響を与えるのでしょうか? もしそうなら、どのようにするのでしょうか?のハッシュを足すだけです。
name
と
data
? 例えば
- (NSUInteger)hash {
NSUInteger hash = 0;
hash += [[self name] hash];
hash += [[self data] hash];
return hash;
}
これでいいのでしょうか? もっと良いテクニックはないのでしょうか? もし、プリミティブがあったらどうでしょうか?
int
? それらを
NSNumber
でハッシュを取得できますか? または、以下のような構造体
NSRect
?
(
脳屁
: 元々は "bitwise OR" と一緒に書きました。
|=
. 追加という意味)
解決方法は?
まずは
NSUInteger prime = 31;
NSUInteger result = 1;
そして、すべてのプリミティブに対して、次のようにします。
result = prime * result + var
オブジェクトの場合、nil には 0 を、それ以外の場合はハッシュコードを使用します。
result = prime * result + [var hash];
ブーリアンには、2つの異なる値を使用します。
result = prime * result + ((var)?1231:1237);
説明と帰属
これはtcurdtさんの作品ではありませんし、コメントでもっと説明を求められたので、帰属のための編集は妥当だと思います。
このアルゴリズムは、書籍 "Effective Java" で一般化されており 該当の章は現在オンラインで見ることができます。 . この本はこのアルゴリズムを普及させ、今では多くのJavaアプリケーション(Eclipseを含む)でデフォルトになっています。 しかし、このアルゴリズムは、Dan BernsteinまたはChris Torekのものとされる、さらに古い実装に由来しています。 この古いアルゴリズムは、もともとUsenetで出回っていたものであり、確実な帰属は困難である。 例えば、いくつかの このApacheのコードには、興味深い解説があります。 (名前を検索してください)で、元のソースを参照しています。
要するに、これは非常に古く、シンプルなハッシュアルゴリズムだということです。 最も高性能というわけではありませんし、数学的に良いアルゴリズムであることが証明されているわけでもありません。 しかし、シンプルであり、多くの人が長い間使って良い結果を出してきたため、歴史的に多くの支持を得ています。
関連
-
[解決済み] Objective-CのNSLog関数でNSString型を出力する方法とは?
-
[解決済み] Objective-Cでオブジェクトをキャストする方法
-
[解決済み] 警告 : フォーマット文字列は文字列リテラルではありません (安全でない可能性があります)
-
[解決済み] NSTaggedPointerStringをNSStringに変換する。
-
[解決済み] Objective-CでNSNumberをintに変換する。
-
非静的宣言に続く "****"の静的宣言
-
[解決済み] SwiftからObjective-Cのコードを呼び出すにはどうしたらいいですか?
-
[解決済み] Objective-Cで、オブジェクトの種類をテストするにはどうしたらいいですか?
-
[解決済み] synthesize vs @dynamic、その違いとは?
-
[解決済み】iOS7でステータスバーを隠すことができない。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Objective-Cでオブジェクトをキャストする方法
-
[解決済み] NSNumberをNSStringに変換する方法
-
[解決済み] インスタンスに送信されたセレクタが認識されない」を解決するには?
-
[解決済み] iOS 8で位置情報サービスが利用できない
-
[解決済み】キーボードを簡単に解除する方法は?
-
[解決済み】Objective-Cのシングルトンはどのように見えるべきですか?[クローズド]
-
[解決済み】SwiftのコードをObjective-Cにインポートするにはどうすればいいですか?
-
[解決済み】メインスレッドでタスクを実行するGCD
-
[解決済み】コンパイルの警告:アーキテクチャi386のファイルを処理するルールがない
-
[解決済み】UITableViewからセパレータラインを削除する方法はありますか?