1

我正在尝试编写一个例程,该例程从制表符分隔的文件中将数百条客户记录导入到 NSArrayController 中。

这是我的初始代码:

NSString *stringFromFile = [NSString stringWithContentsOfFile:[fileURL path]
                                encoding:NSUTF8StringEncoding error:&error];
NSArray *paragraphsArray = [stringFromFile componentsSeparatedByString:@"\r"];
NSMutableDictionary *destDict = [[NSMutableDictionary alloc] init];

int i;
for (i = 0; i <= [paragraphsArray count]-1; i++) {
    NSString *currentParagraph = [paragraphsArray objectAtIndex:i];
    if ([currentParagraph length ] > 4) {
        NSArray *elementsArray = [currentParagraph componentsSeparatedByString:@"\t"];
        if ([elementsArray count] > 0) {
            currentSerial++;
            [destDict setObject:[NSString stringWithFormat:@"%ld",currentSerial]
                         forKey:@"idSerial"];
            [destDict setObject:[elementsArray objectAtIndex:1]
                         forKey:@"destRazaoSocial"];
            [destDict setObject:[elementsArray objectAtIndex:2]
                         forKey:@"destLogradouro"];
            [destDict setObject:[elementsArray objectAtIndex:3]
                         forKey:@"destLogradouroNro"];
            /// repeat this for every field...
            //Add the record:
            [destArrayController addObject:destDict];
        }
    }
}

这段代码导致插入错误的记录,如果我在一个例子中有4条记录,插入的4条记录将与最后一条记录具有相同的内容。

但是,如果我将代码更改为此,分配 destDict 并在每个循环中丢弃它,它就可以工作:

NSString *stringFromFile = [NSString stringWithContentsOfFile:[fileURL path]
                                   encoding:NSUTF8StringEncoding error:&error];
NSArray *paragraphsArray = [stringFromFile componentsSeparatedByString:@"\r"];
int i;
for (i = 0; i <= [paragraphsArray count]-1; i++) {
    NSString *currentParagraph = [paragraphsArray objectAtIndex:i];
    if ([currentParagraph length ] > 4) {
        NSArray *elementsArray = [currentParagraph componentsSeparatedByString:@"\t"];
        if ([elementsArray count] > 0) {
            NSMutableDictionary *destDict = [[NSMutableDictionary alloc] init];
            currentSerial++;
            [destDict setObject:[NSString stringWithFormat:@"%ld",currentSerial]
                         forKey:@"idSerial"];
            [destDict setObject:[elementsArray objectAtIndex:1]
                         forKey:@"destRazaoSocial"];
            [destDict setObject:[elementsArray objectAtIndex:2]
                         forKey:@"destLogradouro"];
            [destDict setObject:[elementsArray objectAtIndex:3]
                         forKey:@"destLogradouroNro"];
            /// repeat this for every field...
            //Add the record:
            [destArrayController addObject:destDict];
            [destDict release];
        }
    }
}

这可行,但对我来说看起来并不优雅。你能告诉我正确的方法吗?

4

2 回答 2

1

The reason why the first code does not work is that you are creating the NSMutableDictionary outside of the loop, changing its contents, and then adding it multiple times to an array.

When you add an object to an array, it doesn't create an actual copy of the object, but instead, the array simply sends that object a retain message. So in your first code segment, because you created the destDict instance outside of the loop, you end up adding the same destDict instance to the array multiple times. Because it's the same instance, the dictionary will effectively have the contents from the changes you made on the very last loop.

You can use the code like in your second example, but instead of creating the destDict using alloc/init, just create an auto-released instance using [NSMutableDictionary dictionary]. Then there's no need to add the [destDict release]; line after adding it to the array controller. (Not a big deal, but anyway)...

NSString *stringFromFile = [NSString stringWithContentsOfFile:[fileURL path]
                                encoding:NSUTF8StringEncoding error:&error];
NSArray *paragraphsArray = [stringFromFile componentsSeparatedByString:@"\r"];
int i;
for (i = 0; i <= [paragraphsArray count]-1; i++) {
    NSString *currentParagraph = [paragraphsArray objectAtIndex:i];
    if ([currentParagraph length ] > 4) {
        NSArray *elementsArray = [currentParagraph componentsSeparatedByString:@"\t"];
        if ([elementsArray count] > 0) {

            NSMutableDictionary *destDict = [NSMutableDictionary dictionary];

            currentSerial++;
            [destDict setObject:[NSString stringWithFormat:@"%ld",currentSerial]
                         forKey:@"idSerial"];
            [destDict setObject:[elementsArray objectAtIndex:1]
                         forKey:@"destRazaoSocial"];
            [destDict setObject:[elementsArray objectAtIndex:2]
                         forKey:@"destLogradouro"];
            [destDict setObject:[elementsArray objectAtIndex:3]
                         forKey:@"destLogradouroNro"];
            /// repeat this for every field...
            //Add the record:
            [destArrayController addObject:destDict];
        }
    }
}
于 2012-11-01T18:31:57.670 回答
1

以您发布的第二种方式进行操作没有任何问题。另一种方法(可能更好也可能不会更好)是第一种方法,但是将 [destDict copy] 而不是 destDict 添加到您的数组中。

关于你的 for 循环的另一点——如果你不需要使用你的代码中没有的索引,你应该使用快速枚举。它更快更容易编写。所以这:

int i;
for (i = 0; i <= [paragraphsArray count]-1; i++) {
    NSString *currentParagraph = [paragraphsArray objectAtIndex:i];

可以这样完成(称为 for-in 循环):

for (NSString *currentParagraph in paragraphArray){
    ....
    ....
}
于 2012-11-01T17:03:24.020 回答