试图创建一个字典数组,继续在数组中重复相同的字典

时间:2014-03-19 02:28:49

标签: ios objective-c arrays dictionary

我正在尝试使用NSData从文本文件中提取信息,然后将其加载到字典中。

首先,我创建一个文本文件的字符串,并将每个记录加载到一个数组中。

然后我将每条记录拆分为单独的数据元素。

我遇到的问题是,当字典完全填充后,我会使用addObject将其加载到数组中,它确实成功完成了。问题是,当下一个循环创建一个新字典时,同一个字典被加载到数组中,我最终得到一个包含所有相同字典的数组,而不是多个不同的字典对象。

我猜我有一些简单的错误导致了这个错误。任何帮助将不胜感激。

NSString * clientListFile = [NSURL URLWithString:@“/ textfile”];

NSData *clientListDataFile = [NSData dataWithContentsOfFile:clientListFile];

NSString *clientListString = [[NSString alloc]initWithBytes:[clientListDataFile bytes] length:[clientListDataFile length] encoding:NSUTF8StringEncoding];

NSString *returnDelimiter = @"\n";
NSString *commaDelimiter = @",";
NSString *exclamationDelimiter = @"!";

NSArray *keysAndObjects = [[NSArray alloc]init];
NSMutableDictionary *clientList = [[NSMutableDictionary alloc]init];
NSMutableArray *clientListOfDictionaries = [[NSMutableArray alloc]init];

NSArray *sentenceArray = [clientListString componentsSeparatedByString:returnDelimiter];
    for (int i = 0; i < [sentenceArray count]; i=i+1) {
        [clientList removeAllObjects]; //to start with a fresh dictionary for the next iteration
        NSString *recordSentence = [sentenceArray objectAtIndex:i];

        NSArray *attributes = [recordSentence componentsSeparatedByString:commaDelimiter];

        for (int j = 0; j < [attributes count]; j = j+1) {
            NSString *pairsOfItems = [attributes objectAtIndex:j];

            //a small arry, of only two objects, the first is the key, the second is the object
            keysAndObjects = [pairsOfItems componentsSeparatedByString:exclamationDelimiter];


            [clientList setObject:[keysAndObjects lastObject] forKey:[keysAndObjects firstObject]];


            }
        [clientListOfDictionaries addObject:clientList];

        }

当我使用NSLog查看字典中的内容时,我重复了同一个字典的多个对象,即使在迭代的早期,我可以看到代码正在创建单独且独特的字典。

5 个答案:

答案 0 :(得分:0)

移动此行:

NSMutableDictionary *clientList = [[NSMutableDictionary alloc]init];

到第一个for循环行之后,然后删除该行:

[clientList removeAllObjects];

为每次迭代创建一个新字典非常重要。

您还应删除以下行:

NSArray *keysAndObjects = [[NSArray alloc]init];

并改变:

keysAndObjects = [pairsOfItems componentsSeparatedByString:exclamationDelimiter];

为:

NSArray *keysAndObjects = [pairsOfItems componentsSeparatedByString:exclamationDelimiter];

答案 1 :(得分:0)

您在for循环之外分配并初始化了clientList字典,因此您只有一个字典,您将多次存储在数组中。将字典添加到数组不会复制它,它只是添加指向对象的指针。

你需要搬家

NSMutableDictionary *clientList = [[NSMutableDictionary alloc]init];

在你的第一个for循环中代替

[clientList removeAllObjects];

此外,componentsSeparatedByString:会返回NSArray,因此您无需分配和初始化NSArray。您可以简单地定义变量 -

NSArray *keysAndObjects;

答案 2 :(得分:0)

而不是这一行

[clientListOfDictionaries addObject:clientList];

你可以

[clientListOfDictionaries addObject:[[NSArray alloc] initWithArray:clientList];

这样你就可以将新数组添加到clientListOfDictionaries而不是同一个数组。

答案 3 :(得分:0)

因为您在循环的每次迭代中使用相同的clientList变量。您需要每次都创建一个全新的字典对象。

尝试修改后的代码:

NSData *clientListDataFile = [NSData dataWithContentsOfFile:clientListFile];
NSString *clientListString = [[NSString alloc]initWithBytes:[clientListDataFile bytes] length:[clientListDataFile length] encoding:NSUTF8StringEncoding];

NSString *returnDelimiter = @"\n";
NSString *commaDelimiter = @",";
NSString *exclamationDelimiter = @"!";

NSArray *keysAndObjects = nil;
NSMutableArray *clientListOfDictionaries = [[NSMutableArray alloc] init];

NSArray *sentenceArray = [clientListString componentsSeparatedByString:returnDelimiter];

for (NSUInteger i = 0; i < [sentenceArray count]; ++i) {
    NSMutableDictionary *clientList = [[NSMutableDictionary alloc] init]; //to start with a fresh dictionary for the next iteration
    NSString *recordSentence = [sentenceArray objectAtIndex:i];

    NSArray *attributes = [recordSentence componentsSeparatedByString:commaDelimiter];

    for (NSUInteger j = 0; j < [attributes count]; ++j) {
        NSString *pairsOfItems = [attributes objectAtIndex:j];

        //a small arry, of only two objects, the first is the key, the second is the object
        keysAndObjects = [pairsOfItems componentsSeparatedByString:exclamationDelimiter];

        [clientList setObject:[keysAndObjects lastObject] forKey:[keysAndObjects firstObject]];
    }

    [clientListOfDictionaries addObject:clientList];
}

另一种选择,虽然可能效率较低,但是要改变这一行:

[clientListOfDictionaries addObject:clientList];

[clientListOfDictionaries addObject:[clientList copy]];

这使您可以继续使用相同的clientList变量,因为您要将其副本添加到clientListOfDictionaries数组中。我只是指出这一点,因为它可以帮助你理解正在发生的事情。

另外,请注意我为您更改了此行:

NSArray *keysAndObjects = [[NSArray alloc]init];

NSArray *keysAndObjects = nil;

因为它只是通过调用componentsSeparatedByString设置的指针,所以不需要为它分配数组。该数组将在循环的第一次迭代中消失。

答案 4 :(得分:0)

应该将新词典添加到数组中。否则它将不会添加到数组。数组中的每个对象都有相同的字典映射。所以它会给你相同的字典值。为每个对象创建新字典并添加到数组。

for (int i = 0; i < [sentenceArray count]; i=i+1) {

    NSMutableDictionary *clientList = [[NSMutableDictionary alloc]init];

    NSString *recordSentence = [sentenceArray objectAtIndex:i];

    NSArray *attributes = [recordSentence componentsSeparatedByString:commaDelimiter];

    for (int j = 0; j < [attributes count]; j = j+1) {

        NSString *pairsOfItems = [attributes objectAtIndex:j];

        //a small arry, of only two objects, the first is the key, the second is the object
        NSArray *keysAndObjects = [pairsOfItems componentsSeparatedByString:exclamationDelimiter];

        [clientList setObject:[keysAndObjects lastObject] forKey:[keysAndObjects firstObject]];

        }

    [clientListOfDictionaries addObject:clientList];

    }