2009-10-20 74 views
2

我有一種情況,我想將一對對象映射到信息字典。我想避免創建NSDictionaries的NSDictionary的NSDictionary,因爲這只是混亂和難以維護。我應該如何構造一個帶有多個鍵的NSDictionary?

舉例來說,如果我有兩個班,Foo和酒吧,我想{美孚,酒吧} - > {NSDictionary中}

是否有不只是做一個自定義類(只用作字典其他選項關鍵)基於兩種類型的問題?也許類似於我不知道的STL的配對類型?

回答

5

就像你說的,你可以創建一個Pair類:

//Pair.h 
@interface Pair : NSOpject <NSCopying> { 
    id<NSCopying> left; 
    id<NSCopying> right; 
} 
@property (nonatomic, readonly) id<NSCopying> left; 
@property (nonatomic, readonly) id<NSCopying> right; 
+ (id) pairWithLeft:(id<NSCopying>)l right:(id<NSCopying>)r; 
- (id) initWithLeft:(id<NSCopying>)l right:(id<NSCopying>)r; 
@end 

//Pair.m 
#import "Pair.h" 
@implementation Pair 
@synthesize left, right; 

+ (id) pairWithLeft:(id<NSCopying>)l right:(id<NSCopying>)r { 
return [[[[self class] alloc] initWithLeft:l right:r] autorelease]; 
} 

- (id) initWithLeft:(id<NSCopying>)l right:(id<NSCopying>)r { 
    if (self = [super init]) { 
    left = [l copy]; 
    right = [r copy]; 
    } 
    return self; 
} 

- (void) finalize { 
    [left release], left = nil; 
    [right release], right = nil; 
    [super finalize]; 
} 

- (void) dealloc { 
    [left release], left = nil; 
    [right release], right = nil; 
    [super dealloc]; 
} 

- (id) copyWithZone:(NSZone *)zone { 
    Pair * copy = [[[self class] alloc] initWithLeft:[self left] right:[self right]]; 
    return copy; 
} 

- (BOOL) isEqual:(id)other { 
    if ([other isKindOfClass:[Pair class]] == NO) { return NO; } 
    return ([[self left] isEqual:[other left]] && [[self right] isEqual:[other right]]); 
} 

- (NSUInteger) hash { 
    //perhaps not "hashish" enough, but probably good enough 
    return [[self left] hash] + [[self right] hash]; 
} 

@end 

編輯:

上創建對象,可以是鍵的一些注意事項:

  1. 他們必須符合NSCopying協議,因爲我們不希望密鑰從我們下面改變。
  2. 由於Pair本身被複制,我確保對中的對象也被複制。
  3. 鑰匙必須執行isEqual:。我實施了hash方法,但這可能沒有必要。
+0

Dave,2個問題。 1)我想在copyWithZone中使用allocWithZone,對吧? 2)使用id 代替NSObject *有什麼好處嗎? – nall 2009-10-20 06:16:01

+3

如果你實現isEqual:你必須實現-hash。不變量是,如果[a isEqual:b],那麼[一個散列]必須== [b散列]。 – Ken 2009-10-20 07:01:23

+0

@nall(抱歉,錯過了你的評論)1:通過調用'+ allocWithZone:'來實現'alloc alloc',所以它可能不會有所作爲。 2:沒有真正的好處。我更喜歡'id ',因爲它a)少了類型,b)初始化器返回了'id',而不是'NSObject *'(或類似的變體)。確實,你很少*有一個初始化器不會返回一些'NSObject'子類,但這不是不可能的。 'NSObject'不是唯一的根類。 – 2009-11-01 04:40:30

3

你可以試試NSMapTable,那麼你的密鑰幾乎可以是任何東西,如果你願意,也許是指向結構的指針。

(補遺下面的評論:NSMapTable曾經是不是在iOS上,但可通過iOS 6)

+0

這是一個很好的提示,但NSMapTable不適用於iOS(目前5.0.1)。 – auco 2011-12-28 17:50:42

+0

這樣做有一定道理,因爲NSMapTable主要是作爲Objective-C垃圾收集的輔助工具開發的(儘管它在非GC環境中非常有用)。如果你想要類似於NS(可變)字典但支持非對象類型的東西,總是有CFMutableDictionary。 – 2011-12-28 18:37:23

+0

有關NSMapTable的更多信息:http://stackoverflow.com/questions/6904533/nsmaptable-and-nsmutabledictionary-differences/12186329#12186329 – 2012-08-29 20:56:24

0

正在用東西

的效果[的NSString stringWithFormat:@ 「%@%@」,[OBJ1 key_as_string],[oj2 key_as_string]

沒有對你有好處,其中key_as_string是你的對象類的一部分?即從一個字符串中創建一個鍵。

相關問題