Objective-C的HashMap等价物

25

我正在尝试转换一段使用HashMap的Java代码,其中包含一个对象作为键和一个对象作为值。

private static HashMap<Class<? extends Component>, ComponentType> componentTypes = new HashMap<Class<? extends Component>, ComponentType>();
我一直在学习如何使用Obj-C实现这个功能,但我还没有成功。大多数人建议使用NSDictionary,但问题是它们的键需要是字符串而我需要它们作为对象。另一个选择是NSMapTable,但它在iOS上不可用。请问有谁能帮助我将其转换为Obj-C等效代码吗?
谢谢。
5个回答

25

NSDictionary 的键不需要是字符串,可以是任何实现 NSCopying 协议的对象。但如果该对象是自定义对象,则需要对 -hash-isEqual: 消息做出正确的响应。不过这与在 Java 集合中使用对象相同,因此不应该太难。


17
一个 NSMutableDictionary(假设在初始化后还需要设置字典中的值)有两种用法:
  1. 作为传统的字典/哈希表,在其中设置值的方式如下:

    [myDictionary setObject:theValue forKey:anyObject];

  2. 作为具有符合KVC规则属性的对象,其属性是动态定义的:

    [myDictionary setValue:theValue forKey:aString];

如果键是 NSString,则这两种方式可以互换使用,唯一的例外是你不能使用 setObject:forKey: 设置一个对象为 nil,但你可以将 nil 传递给 setValue:forKey:

8
你想使用一个`NSDictionary`。你说: > 键需要是字符串,我需要它们作为对象。
`NSDictionary`的键不需要是字符串 - 它们可以是任何符合`NSCopying`协议的对象。

2
这是正确的。请注意,有一种常见情况下 NSDictionary 需要字符串键:如果预计该 NSDictionary 将用于属性列表中。 - Mike Mertsock

3

来自NSDictionary参考文档

字典中的键值对称为条目。每个条目包含一个表示键的对象和一个表示该键值的第二个对象。在字典中,键是唯一的。也就是说,在单个字典中没有两个键相等(由isEqual:确定)。通常情况下,键可以是任何对象(前提是它符合NSCopying协议-请参见下文),但请注意,使用键值编码时,键必须是字符串(请参见“键值编码基础知识”)。键或值都不能为nil;如果您需要在字典中表示空值,则应使用NSNull。

因此,任何符合NSCopying协议的对象都可以用作键。字符串限制仅适用于用于Cocoa绑定的键值编码。


1

我猜测您正在使用不符合NSCopying协议的键。在这种情况下,请尝试使用NSDictionary的Core Foundation等效项:CFDictionary。

http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFDictionaryRef/Reference/reference.html

在使用CFDictionary时,请确保所有对象在对象的生命周期内都将被保留在内存中。由于CFDictionary必须使用弱引用设置(至少在我的经验中是这样),请注意不要在对象仍在CFDictionary中时意外释放其中一个对象。

虽然CFDictionary与其Cocoa Foundation对应项NSDictionary“无缝桥接”,但我发现仍存在问题。我曾尝试向我的无缝桥接NSDictionary添加未包含在NSCopying协议中的对象,结果在运行时出现错误。

CFDictionary文档:http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFDictionaryRef/Reference/reference.html

如果需要可变性,请改用CFMutableDictionary,如下所示: cfd = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); CFDictionaryAddValue(cfd, key, value); CFRelease(cfd);

CFMutableDictionary文档: http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFMutableDictionaryRef/Reference/reference.html#//apple_ref/doc/uid/20001497


嗨,感谢所有的回复。如果我正在使用ARC并且使用CFDictionary,我仍然需要处理内存吗? - Black20
如果您在CFDictionary中使用ARC,除非您决定使用toll free bridging,否则您将不得不处理内存。个人而言,我无法使toll free bridging为我正常工作,因为它一直试图复制未符合NSCopying的对象。 - bendu
以下是有关此事的更多信息,请向下滚动至免费通行桥部分:http://developer.apple.com/library/ios/releasenotes/ObjectiveC/RN-TransitioningToARC/_index.html#//apple_ref/doc/uid/TP40011226-CH1-DontLinkElementID_5 - bendu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接