NSMutableDictionary,来自控制台和代码的不同打印

时间:2011-12-02 17:18:36

标签: objective-c ios4 nsmutabledictionary

我对NSMutableDictionary有一些疑问。我读到它们只是一个hashmap的包装器,因此不鼓励它们用于有序列表。

但我必须使用它,所以问题就开始了......

我在NSMutableDictionary中保存了Json的结果(在调用URL之后),然后我有两个不同的“print”:

  • 如果我尝试使用命令“po myDictionary”从控制台打印字典,我有一个订单(原始json的顺序)
  • 如果我创建一个简单的“for statement”并打印myDictionary中的每个元素,我会有不同的顺序。

怎么可能?他们不应该有相同的订单吗?

感谢所有人!

编辑:这是代码的一个小例子:

NSMutableDictionary *myDictionary = [--{RECEIVED FROM ANOTHER CALL}--];
NSMutableDictionary *tmp = [NSMutableDictionary dictionaryWithCapacity:[myDictionary count]];

for(NSString *key in myDictionary) {
    NSLog(@"%@", key);

    NSObject *object = [[NSObject alloc] init]

    /* some operation in the code with object */

    [tmp setObject:object forKey:key];
}

在“for statement”之后发生了这样的事情:

  • 如果我看到所有日志,我会收到一些东西(例如,如果myDictionary有一天的名字我有“星期六,星期一,星期五......”)
  • 如果我在这里插入断点并尝试使用命令“po myDictionary”从控制台打印某些内容我还有另一个订单,(“星期日,星期二,星期一,......”)

问题是:为什么?

编辑2:我知道存在一个拥有“OrderedDictionary”的系统,但这不是问题:我想理解为什么我有两个不同的印刷品,一个来自“声明“和另一个”po命令“。

4 个答案:

答案 0 :(得分:5)

gdb中的po <object>命令打印[<object> description]的输出。 [NSDictionary description]按键对其输出进行排序。这是documented behavior

如果您的JSON按键排序(它听起来像是这样),那么您可以再次按键排序以确保可靠的订单。

请注意,如果您的JSON使用对象(键/值对的集合)来表示有序数据,则它违反了JSON spec

  

对象是零个或多个名称/值对的无序集合,其中名称是字符串,值是字符串,数字,布尔值,空值,对象或数组。 / p>

正确的编码是单键对象的数组,例如:

[ { "firstKey": "value" }, { "secondKey": "value" } ]

但是如果你可以使用排序键来定义顺序,那就合适了。

答案 1 :(得分:2)

NS(Mutable)字典未订购,期间。 (这不仅仅是气馁。)即使您获得po提供的“原始订单”,也无法保证从应用启动到应用启动,或从操作系统版本到操作系统版本,或者从硬件到硬件。不要那样做。

也许你想使用像http://cocoawithlove.com/2008/12/ordereddictionary-subclassing-cocoa.html这样的东西?

答案 2 :(得分:2)

Hashmap没有键或值顺序,也没有承诺任何订单。如果您需要相同的订单,则可以使用键值对数组,或使用http://cocoawithlove.com/2008/12/ordereddictionary-subclassing-cocoa.html

答案 3 :(得分:1)

您可能更喜欢有序词典:http://cocoawithlove.com/2008/12/ordereddictionary-subclassing-cocoa.html

好的,您现在修改了原始问题。你现在要问:

  

我知道有一个系统有一个&#34; OrderedDictionary&#34;但它不是问题:我想理解为什么我有两个不同的印刷品,一个来自&#34;声明&#34;另一个来自&#34; po命令&#34;。

这是因为它们是两种完全不同的访问数据的方式。 for语句按某种顺序逐个遍历键。 po命令调用字典的description方法,该方法显然不包含枚举像你这样的密钥的for语句。我不明白为什么你会发现这令人费解。