Странное поведение NSMutableDictionary - PullRequest
0 голосов
/ 11 ноября 2011

Взгляните на этот кусок кода

- (NSMutableDictionary *)getUsersFromServer
{
//here we're getting list of users from the server
NSMutableDictionary * users = [[[NSMutableDictionary alloc] init] autorelease];

userresults = [[NSMutableArray alloc] init];    

//all this will be replaced with users taken from the server. it's needed just for testing
for (int i = 0;i < 19;i++)
{

    int wins    = i ;         float f_wins = (float)wins;
    int losses  = i * 2 ;     float f_losses = (float)losses;
    int withdr  = i * 3 ;     float f_withdr = (float)withdr;
    float win_per = f_wins / ((f_wins + f_losses + f_withdr) / 100.0);

 [userresults setArray:[NSMutableArray arrayWithObjects:[NSNumber numberWithInt:wins],
                                                                                [NSNumber numberWithInt:losses],
                                                                                [NSNumber numberWithInt:withdr],
                                                                                [NSNumber numberWithFloat:win_per],
                                                                                 nil]]; 
[users setObject:userresults forKey:[NSString stringWithFormat:@"user number %i",i]];

}

[userresults release];
return users;
}

в каждой итерации цикла, я заполняю массив числами и устанавливаю его как значение в NSMutableDictionary.Ключом для каждого массива служит отформатированная строка, уникальная по номеру счетчика итераций.Итак ... проблема в том, что словарь всегда заполнен ЖЕ массивами для РАЗЛИЧНЫХ ключей.В словаре 19 массивов, и ВСЕ ОНИ ПОСЛЕДНИЕ !!!!Это из последней итерации.И у каждого свой ключ !!!Как это могло случиться ???В чем дело???

Ответы [ 2 ]

3 голосов
/ 11 ноября 2011

userresults указывает на тот же объект, и вы модифицируете тот же массив с помощью метода setArray:. Вместо этого создайте новый массив в каждой итерации цикла:

NSArray *userData = [NSArray arrayWithObjects:[NSNumber numberWithInt:wins],
                                              [NSNumber numberWithInt:losses],
                                              [NSNumber numberWithInt:withdr],
                                              [NSNumber numberWithFloat:win_per],
                                              nil];
[users setObject:userData forKey:[NSString stringWithFormat:@"user number %i",i]];
0 голосов
/ 11 ноября 2011

userresults объявляется вне цикла без необходимости.Здесь вы можете отказаться от изменяемых массивов и просто создавать новый NSArray с каждой итерацией.Ваша проблема связана с повторным использованием массива, объявленного вне цикла, и добавлением новых значений каждый раз.Попробуйте это:

[users setObject: [NSArray arrayWithObjects:[NSNumber numberWithInt:wins], [NSNumber numberWithInt:losses], [NSNumber numberWithInt:withdr], [NSNumber numberWithFloat:win_per], nil];
[users setObject:userData forKey:[NSString stringWithFormat:@"user number %i",i]]
forKey:[NSString stringWithFormat:@"user number %i",i]];;
...