此SO answer顯示NSDictionary的散列值是字典中條目的數量。 (Similarly, the hash of an NSArray is its length。)答案繼續建議創建一個類別以提供更好的散列實現。覆蓋NSArray的散列值
如果您需要更準確的散列值,您可以在Obj-C類別中自己提供一個 。
但是,當我嘗試這個,似乎無論如何使用原始的哈希實現。
我們在NSDictionary+Hash.m
在NSDictionary+Hash.h
#import <Foundation/Foundation.h>
@interface NSDictionary (Hash)
- (NSUInteger)hash;
@end
頁眉和執行:
#import "NSDictionary+Hash.h"
@implementation NSDictionary (Hash)
- (NSUInteger)hash
{
// Based upon standard hash algorithm ~ https://stackoverflow.com/a/4393493/337735
NSUInteger result = 1;
NSUInteger prime = 31;
// Fast enumeration has an unstable ordering, so explicitly sort the keys
// https://stackoverflow.com/a/8529761/337735
for (id key in [[self allKeys] sortedArrayUsingSelector:@selector(compare:)]) {
id value = [self objectForKey:key];
// okay, so copying Java's hashCode a bit:
// http://docs.oracle.com/javase/6/docs/api/java/util/Map.Entry.html#hashCode()
result = prime * result + ([key hash]^[value hash]);
}
return result;
}
一個簡單的單元測試顯示了原始的實現是在使用中:
#import "NSDictionary+Hash.h"
#import <SenTestingKit/SenTestingKit.h>
@interface NSDictionary_HashTest : SenTestCase
@end
@implementation NSDictionary_HashTest
- (void)testHash
{
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
@"val1", @"key1", @"val2", @"key2", nil];
NSUInteger result = 1;
result = 31 * result + ([@"key1" hash]^[@"val1" hash]);
result = 31 * result + ([@"key2" hash]^[@"val2" hash]);
STAssertEquals([dict hash], result, nil);
}
@end
這測試失敗,「2」應該等於「2949297985」。
現在,如果我在類別標題和實現文件中將方法從哈希重命名爲hashy(例如),那麼[dict hashy]
會返回正確的值。是否可以重寫某個類別中的「內置」方法?我在做別的事嗎?
科迪,你絕對可以用類別覆蓋內建的方法。 – xyzzycoder
它曾經是這種情況,我不確定當前的情況,如果你有兩個實現了相同方法名的類,並且這兩個類都是單個類的一部分,那麼鏈接順序決定了哪個方法會被調用由運行時。 Objective-C在過去五年中發生了很大變化,所以現在這種行爲可能會有所不同。 – xyzzycoder