2010-03-29 65 views
2

我有一組類來表示從數據庫加載的一些對象。這些對象有幾個變體,所以我有一個共同的基類和兩個子類來表示差異。他們共同的關鍵領域之一是一個id字段。這是一個安全/有效的哈希方法實現?

不幸的是,對象的id在所有變體中並不是唯一的,而是在單個變體中。我的意思是,類型A的單個對象可以具有介於0和1000000之間的id。類型B的對象可以具有介於25,000和1,025,000之間的ID。這意味着ID號碼有一些重疊。儘管如此,對象只是同一類事物的變體,所以我想在我的代碼中將它們想象成這樣。 (他們來自不同的組分配的ID遺留原因。)

所以我上課是這樣的:

@class BaseClass 
@class TypeAClass : BaseClass 
@class TypeBClass : BaseClass 

BaseClass的有一個方法(NSNumber的*)OBJECTID。然而,TypeA和TypeB的實例可能會有上面討論的重疊ID,所以當涉及到平等並將它們放入集合時,我不能僅僅使用id來檢查它。

這些實例的唯一鍵本質上是(class + objectId)。所以我想,我能做到這一點通過使對BaseClass的以下散列函數:

-(NSUInteger)hash 
{ 
    return (NSUInteger)[self class]^[self.objectId hash]; 
} 

我還實施的isEqual像這樣:

- (BOOL)isEqual:(id)object 
{ 
    return (self == object) || ([object class] == [self class] && [self.objectId isEqual:[object objectId]]); 
} 

這似乎是工作,但我想我我只是在這裏問,以確保我沒有忽視某些東西 - 特別是通過使用類指針來生成散列。這是安全還是有更好的方法來做到這一點?

+0

如果你很好奇,這裏有一個鏈接,講述瞭如何在Cocoa中使用散列,並對性能進行傾斜。 http://www.mulle-kybernetik.com/artikel/Optimization/opti-7.html – codewarrior 2010-03-30 00:00:27

回答

2

這可能是安全的,但不一定。根據嚴格的課堂標識,如果你實際上以某種方式結束了某個子類別(例如,如果KVO導致你的課程轉換爲另一個*),則可能會咬你。如果使用某種明確的類ID,它可能會更安全一些。

還要記住,不相等的對象不需要有不同的哈希值。唯一的要求是相同的對象必須具有相同的散列。所以,如果這兩個類中的對象具有相同的散列值,那麼只要這不會使散列表過慢。如果祕密的KVO子類僞裝成父類,那麼在這種情況下你仍然在這裏很安全,但是我通常會盡量避免依賴於類的身份,所以我並不記得我的頭頂)

+0

啊 - 所以哈希只需要返回相同的東西,如果isEqual是YES。這是有道理的,比我想象的要容易得多。所以我可以單獨返回objectId的散列。 (有ID重疊,但實際上它並不常見 - 只是一些我想,以確保不會造成問題。)我還沒有發現有關志願是如何影響這一切還沒有一定的答案,但我沒有改變,isEqual:方法使用isKindOf:而不是直接用==比較類。謝謝! – Sean 2010-03-29 20:17:13