2009-10-20 73 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是你的对象类的一部分?即从一个字符串中创建一个键。

相关问题