添加键/值对会产生具有空值的键

时间:2013-07-23 22:01:50

标签: objective-c cocoa

我遇到的问题是字典timeStamps将所有值都更改为null。即使我将一个键切换为一个值,反之亦然,键也很好。无论顺序如何,值最终都为null,并且键完全按照应有的顺序结束。

这是代码。它是一个xml解析器。它正在构建一个字典,其中包含键的代码数组和值的时间戳数组。键和值是表示类别的并行数组。

所有变量都在其他地方分配和启动。这将导入包含所有这些变量的头文件作为属性。 @property (strong, nonatomic) Type variableName;然后在主文件中有@synthesize variableName行。此外,它有variableName = [[Type alloc] init];。谢谢大家的帮助!

- (void) didStartElement (elementname is passed as xml tag)
{
    //Tells us if we are in the dance categories
    if ([elementName isEqualToString:@"categories"])
    {
        isCategory = YES; // Just tells us we're ready to start reading

    }
    else if ([elementName isEqualToString:@"category"] && isCategory) 
    {
        onCategory = YES; // 
    }
}


- (void) foundCharacters (currentNodeContent is the info between tags)
{
    currentNodeContent = (NSMutableString *) string;
}


- (void) didEndElement
{
    // if leaving dance categories
    if ([elementName isEqualToString:@"Category End"])
    {
        isCategory = NO; // We've left a category
    }
    else if ([elementName isEqualToString:@"code"] && onCategory)
    {
        Code               = currentNodeContent;
        currentNodeContent = nil;
        isWaitingForTime   = YES;
    }

    else if ([elementName isEqualToString:@"time"] && isWaitingForTime)
    {
        [runningList       addObject:Code];
        [runningList   addObject:currentNodeContent];

        isWaitingForTime   = NO;
        currentNodeContent = nil;
        Code               = @"";
    }

    else if ([elementName isEqualToString:@"dances"])
    {
        [timeStamps setObject:runningTimeList forKey:runningList];
        [runningTimeList   removeAllObjects];
        [runningList       removeAllObjects];
    }
}

3 个答案:

答案 0 :(得分:1)

您必须初始化数组和字典 这应该有效:

NSMutableArray *Array1 = [NSMutableArray new];
NSMutableArray *Array2 = [NSMutableArray new];

[Array1 addObject:@"Hello"];
[Array2 addObject:@"Hi"];

NSMutableDictionary *dictionaryOfArrays = [NSMutableDictionary new];

[dictionaryOfArrays setObject:Array2 forKey:Array1];

NSLog(@"dictionary: %@", dictionaryOfArrays);

如果您计划一次只存储一个对象,则无需创建阵列即可。您可以在此方法中设置实际的NSStrings,因为它将任何id作为对象,将字符串作为键。

否则,您应该使用方法setObjects:forKeys:而不是此方法。

答案 1 :(得分:0)

问题是您将可变数组设置为字典的键。数组被复制,然后存储到字典中。如果您不更改数组,objectForKey:将始终返回您要搜索的值。但是如果向它添加任何对象,则数组会发生变异,并且它不再等于存储在字典中的副本。

从代码看起来你根本不需要字典,你只是使用字典来存储每个结果,所以你可能想用timeStamps替换NSMutableSet或者NSMutableArray

PS :还要记得添加runningTimeList的副本,而不是原始数组。这是因为您不是每次结束元素时都创建数组,而只是清空它。这意味着所有键都指向同一个数组。

答案 2 :(得分:0)

我不确定你在这里真正要求的是什么,但让我们看看是否有任何帮助。

首先考虑基于代码片段的方法:

- (void) test
{
   NSMutableArray *Array1 = [NSMutableArray new];
   NSMutableArray *Array2 = [NSMutableArray new];

   [Array1 addObject:@"Hello"];
   [Array1 addObject:@"There"];
   [Array2 addObject:@"Hi"];
   [Array2 addObject:@"Welcome"];

   NSMutableDictionary *dictionaryOfArrays = [NSMutableDictionary new];

   [dictionaryOfArrays setObject:Array2 forKey:Array1];

   // arrays are ordered, use key with elements in different order to show this
   [dictionaryOfArrays setObject:Array2 forKey:@[@"There", @"Hello"]];

   NSLog(@"dictionary: %@", dictionaryOfArrays);
}

这将输出到控制台:

dictionary: {
        (
        There,
        Hello
    ) =     (
        Hi,
        Welcome
    );
        (
        Hello,
        There
    ) =     (
        Hi,
        Welcome
    );
}

显示可以是一个数组 - 并且数组中元素的顺序很重要。

但是你真的想用数组作为键吗?虽然将作为数组是常见的,但密钥也不常作为数组。

你说你得到( )或" null"。那么第一个可能是没有元素的数组 - 这与没有数组不同。对于第二个,您无法将nil存储在NSDictionary中,但如果您查找非存在键的值,则返回nil - 即nil返回是指不存在的密钥。

最后,如果它是相关的,当键/值对被添加到字典时,键被复制,而值只是引用。这意味着如果您使用可变对象作为密钥,例如一个NSMutableString实例,然后对象的后续突变不会影响字典。但是,如果值(键/值对)是一个可变对象,那么查找操作将返回与插入时完全相同的对象,该对象可能在插入后发生了变异。

您在问题中添加的代码根本无法澄清。

希望这里有所帮助。