2009-12-07 41 views
3

我知道你可以使用任何对象作为NSDictionary的关键,但问题是它将能够检索正确的值?支持我有一个条目,其中键= {1,3,5}和值= {@“hello”}。我能通过传入集合{3,5,1}从这个字典条目中检索吗?NSDictionary能否将NSSet作为关键字?

为了说话,是基于指针匹配的关键还是它实际上比较集合的内容? (如果是前者,我该如何克服这一点?)

回答

3

是的,它似乎很好地工作(不知道是否有任何陷阱)。

NSMutableDictionary * dict = [NSMutableDictionary dictionary]; 

NSSet * set; 
set = [NSSet setWithObjects:@"a", @"b", @"c", @"d", nil]; 
[dict setObject:@"1" forKey:set]; 

set = [NSSet setWithObjects:@"b", @"c", @"d", @"e", nil]; 
[dict setObject:@"2" forKey:set]; 

id key; 
NSEnumerator * enumerator = [dict keyEnumerator]; 
while ((key = [enumerator nextObject])) 
    NSLog(@"%@ : %@", key, [dict objectForKey:key]); 

set = [NSSet setWithObjects:@"c", @"b", @"e", @"d", nil]; 
NSString * value = [dict objectForKey:set]; 
NSLog(@"set: %@ : key: %@", set, value); 

输出:

2009-12-08 15:42:17.885 x[4989] (d, e, b, c) : 2 
2009-12-08 15:42:17.887 x[4989] (d, a, b, c) : 1 
2009-12-08 15:42:17.887 x[4989] set: (d, e, b, c) : key: 2 
+3

一个简单的疑难杂症;密钥必须是不可变的,因此在密钥上调用'copy'。所以任何'NSMutableSet'在用作键时都会被复制到一个新的'NSSet'中。 – PeyloW 2009-12-08 11:34:03

+0

键是不可变的,这就是为什么我使用NSSet。 – stefanB 2009-12-08 11:55:44

0

是的。

在IRB试试这个:

require 'osx/cocoa' 
abc=OSX::NSSet.setWithArray([1,2,3]) 
cba=OSX::NSSet.setWithArray([3,2,1]) 
dict=OSX::NSMutableDictionary.dictionary 
dict[abc] = 'hello' 
puts dict[cba] 

(它的工作原理,因为isEqual:方法,当你希望它是和NSDictionary中立足于它的行动对NSSet中是如此)

6

的平等密钥是在有问题的密钥上使用isEqual完成的。因此,{1,3,5}和{3,5,1}的比较(假设数字由NSNUmber实例表示)将为YES。

+4

这和'NSSet'符合'NSCopying',这是'NSDictionary'键的另一个要求。 – 2009-12-07 22:09:57

+1

+1:另外需要注意的是,如果您想使用键值编码来访问/变更它们,字典的键必须是字符串。 – 2009-12-08 00:24:42

1

是(因为一套符合NSCopying并实现isEqual:),有一个陷阱:不要使用可变集合,或任何其他可变对象,作为键。你改变它,于是你将打破你在字典中查找它的价值的能力。

相关问题