2011-09-20 61 views
4

我一直使用帶字符串作爲鍵的NSDictionaries,以及幾乎所有Web/books/etc上的例子。是相同的。我想我會用一個自定義對象來爲它試一試。我落實「copyWithZone」方法來讀取並創建下列基本類:Objective-C:使用自定義對象鍵從NSMutableDictionary獲取值

@interface CustomClass : NSObject 
{ 
    NSString *constString; 
} 

@property (nonatomic, strong, readonly) NSString *constString; 

- (id)copyWithZone:(NSZone *)zone; 

@end 

@implementation CustomClass 

@synthesize constString; 

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     constString = @"THIS IS A STRING"; 
    } 
    return self; 
} 

- (id)copyWithZone:(NSZone *)zone 
{ 
    CustomClass *copy = [[[self class] allocWithZone: zone] init]; 
    return copy; 
} 

@end 

現在,我想只是添加這些對象之一,一個簡單的字符串值,然後獲取字符串值退出登錄到控制檯:

CustomClass *newObject = [[CustomClass alloc] init]; 
NSString *valueString = @"Test string"; 
NSMutableDictionary *dict = 
[[NSMutableDictionary alloc] initWithObjectsAndKeys:valueString, newObject, nil]; 

    NSLog(@"Value in Dictionary: %@", [dict objectForKey: newObject]); 
    // Should output "Value in Dictionary: Test string" 

不幸的是,日誌顯示一個(null)。我很確定我錯過了一些非常明顯的東西,並且覺得我需要另一雙眼睛。

+0

返回方法'allKeys'是什麼? – Nekto

回答

7

NSDictionary主要對象工作過的三種方法:

  • -(NSUInteger)hash
  • -(BOOL)isEqual:(id)other
  • -(id)copyWithZone:(NSZone*)zone

默認NSObject實施hashisEqual:只使用對象的指針,所以當你的對象通過複製副本和原始對象不再相同。

你需要的是這樣的:

@implementation CustomClass 

-(NSUInteger) hash; 
{ 
    return [constString hash]; 
} 

-(BOOL) isEqual:(id)other; 
{ 
    if([other isKindOfClass:[CustomClass class]]) 
     return [constString isEqualToString:((CustomClass*)other)->constString]; 
    else 
     return NO; 
} 
- (id)copyWithZone:(NSZone *)zone 
{ 
    CustomClass *copy = [[[self class] allocWithZone: zone] init]; 
    copy->constString = constString; //might want to copy or retain here, just incase the string isn't a constant 
    return copy; 
} 

@end 

這是一個有點難以從文件發現這一點。該overview for NSDictionary告訴你isEqual:NSCopying

在一個字典,鍵是唯一的。也就是說,單個字典中沒有兩個密鑰是相等的(由isEqual確定:)。通常,密鑰可以是任何對象(只要它符合NSCopying 協議,請參閱下文),但請注意,使用密鑰值編碼時,密鑰 必須是字符串(請參閱「Key-Value Coding Fundamentals」 )。

如果你看看在documentation for -[NSObject isEqual:]它告訴你hash

如果兩個對象是相等的,它們必須具有相同的哈希值。如果您在 子類中定義isEqual:並且打算將該子類的實例放入 集合中,則此最後一點尤其重要。確保你也在你的子類中定義了散列。

+0

是的,如果我有ivars有任何複製的東西,我會在那裏留下一個保留。爲了簡單起見,我只是在類中放置一個常量只讀字符串,以便爲字典鍵獲取對象的概念。只是好奇,似乎顯而易見的問題是我沒有實現字典所需的方法。由於我不符合任何協議,我怎麼會知道我需要實現什麼方法來實現這個工作(除了做一個計算器搜索)。通過這種方式,我可以在未來爲自己尋找其他類似的東西。 – 5StringRyan

+0

我已經用Apple的文檔中的一些鏈接/引用更新了答案。 –

+0

謝謝。我只有兩個問題。 1)我是否需要將這些實現中的方法添加到接口文件中?爲什麼或者爲什麼不? 2)它看起來像散列和等同的方法正在基於該恆定字符串進行測試。所以,如果我將它用於一個完整的類,我將如何去更新哈希方法?我假設isEqual,我將不得不詳盡測試每個伊娃,以確保兩個對象實際上是平等的。 – 5StringRyan

0

我想你的類需要定義:

- (BOOL)isEqual:(id)anObject 

這就是可能是所使用的字典來判斷,如果你的關鍵是等於在字典中已經使用的一個。