2

私が達成しようとしているのは、csvファイルをカスタムオブジェクトの配列に変換することですが、これを試みると、配列内のすべてのオブジェクトが同じオブジェクト(配列内の最後のオブジェクト)として返されるようです)。

さらに説明する前に、コードを次に示します。

- (NSArray *)arrayFromCSVFileName:(NSString *)csvFileName fileType:(NSString *)fileType {

// Convert the file into an NSData object
NSString *studentFilePath = [[NSBundle mainBundle] pathForResource:csvFileName ofType:fileType];
NSData *studentData = [NSData dataWithContentsOfFile:studentFilePath];

// Convert the NSData into an NSString
NSString *csvString = [[NSString alloc] initWithData:studentData encoding:NSUTF8StringEncoding];

// Split each record (line) in the csvDataString into an individual array element (split on the newline character \n)
NSArray *csvArray = [csvString componentsSeparatedByString:@"\n"];

// Create an array to hold the parsed CSV data
NSMutableArray *parsedCSVArray = [[NSMutableArray alloc] init];

NSMutableArray *elementArray = [[NSMutableArray alloc] init];

CGSElement *elementToAdd = [[CGSElement alloc] init];

// Loop through each line of the file
for (int i = 0; i < [csvArray count]; i++) {

    // Get a reference to this record (line) as a string, and remove any extranous new lines or alike
    NSString *csvRecordString = [[csvArray objectAtIndex:i] stringByReplacingOccurrencesOfString:@"\r" withString:@""];

    // Split the line by the comma delimeter
    NSArray *csvRecordArray = [csvRecordString componentsSeparatedByString:@","];

    // Check that there are actually fields (i.e. this is not a blank line)
    if ( ([csvRecordArray count] > 0) && ([[csvRecordArray objectAtIndex:0] length] > 0) ) {

        elementToAdd.mass = [[csvRecordArray objectAtIndex:1] floatValue];
        elementToAdd.atomicNumber = [[csvRecordArray objectAtIndex:0] intValue];
        elementToAdd.name = [csvRecordArray objectAtIndex:2];
        elementToAdd.symbol = [csvRecordArray objectAtIndex:3];
        elementToAdd.period = [[csvRecordArray objectAtIndex:4] intValue];

        [elementArray addObject:elementToAdd];

    }

}

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

    NSLog(@"%i", i);

    CGSElement *current = [elementArray objectAtIndex:i];

    NSLog(@"Name = %@", current.name);

}

// Return the parsed array
return elementArray;
}

問題のカスタム オブジェクトは CGSElement オブジェクトで、これを埋めようとしてelementArrayいます。ただし、私のデバッグ コード (コードの次のセクション):

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

    NSLog(@"%i", i);

    CGSElement *current = [elementArray objectAtIndex:i];

    NSLog(@"Name = %@", current.name);

}

その結果、正しい要素名のすべてが返されるのではなく、最後の要素 (これをコンテキストに入れると ununoctium) が 118 回返されます。

いくつかのテストの後、この時点までは安全に言うことができます:

elementToAdd.mass = [[csvRecordArray objectAtIndex:1] floatValue];
elementToAdd.atomicNumber = [[csvRecordArray objectAtIndex:0] intValue];
elementToAdd.name = [csvRecordArray objectAtIndex:2];
elementToAdd.symbol = [csvRecordArray objectAtIndex:3];
elementToAdd.period = [[csvRecordArray objectAtIndex:4] intValue];

同じ要素が何度も繰り返されるのではなく、すべての要素が正しく定義されています。

言うまでもなく、なぜ同じオブジェクトが何度も返されるのか、私は困惑しています。どんな助けでも大歓迎です。

4

2 に答える 2

1

いつも同じエンティティを追加します。ループの前に一度作成され、ループ内で値が再度変更されてアンガンされ、配列に追加されます。当然、配列内のすべてのアイテムは同じオブジェクトであるため、同じ値を持ちます。

必要に応じて、配列を NSSet で変更します。オブジェクトをセットに追加できるのは 1 回だけであり、最終的には 1 のセットになります。

それを解決するには、この行を移動します

CGSElement *elementToAdd = [[CGSElement alloc] init];

ループの本体の先頭まで、for i新しいインスタンスが反復ごとに、したがって配列のすべてのインデックスに対して作成されるようにします。

于 2013-08-02T11:24:46.577 に答える