Если массив является потокобезопасным, что за проблема с этой функцией? - PullRequest
0 голосов
/ 23 сентября 2011

Я полностью заблудился из-за того, что происходит с моим кодом. Это заставляет меня задуматься и разобраться с поточной концепцией Array.Является ли NSMutableArray ИЛИ NSMutableDictionary потокобезопасным?

Пока мой код находится в процессе выполнения, значения для изменения get MainArray, хотя, это было добавлено в массив.Система очень проста. Я не могу выбраться из этой ловушки.

Эта функция возвращает массив. Что я хочу сделать: - (Массив) (Основной массив) -> (Словарь) со значением ключа (Множественный словарь в основном массиве) -----> Выше словарь содержит 9 массивов.

Это структура, которую я разрабатываю для Array.But еще до

#define TILE_ROWS    3
#define TILE_COLUMNS 3
#define TILE_COUNT   (TILE_ROWS * TILE_COLUMNS)

-(NSArray *)FillDataInArray:(int)counter
{

    NSMutableArray *temprecord = [[NSMutableArray alloc] init];
    for(int i = 0; i <counter;i++)
    {

        if([temprecord count]<=TILE_COUNT)
        {
            NSMutableDictionary *d1 = [[NSMutableDictionary alloc]init];
            [d1 setValue:[NSString stringWithFormat:@"%d/2011",i+1] forKey:@"serial_data"];
            [d1 setValue:@"Friday 13 Sep 12:00 AM" forKey:@"date_data"];
            [d1 setValue:@"Description Details  " forKey:@"details_data"];
            [d1 setValue:@"Subject Line" forKey:@"subject_data"];   
            [temprecord addObject:d1];
            d1= nil;
            [d1 release];

            if([temprecord count]==TILE_COUNT)
            {
                NSMutableDictionary *holderKey = [[NSMutableDictionary alloc]initWithObjectsAndKeys:temprecord,[NSString stringWithFormat:@"%d",[casesListArray count]+1],nil];
                [self.casesListArray addObject:holderKey];
                [holderKey release];
                holderKey =nil;
                [temprecord removeAllObjects];              
            }
        }
        else {
            [temprecord removeAllObjects];
            NSMutableDictionary *d1 = [[NSMutableDictionary alloc]init];
            [d1 setValue:[NSString stringWithFormat:@"%d/2011",i+1] forKey:@"serial_data"];
            [d1 setValue:@"Friday 13 Sep 12:00 AM" forKey:@"date_data"];
            [d1 setValue:@"Description Details  " forKey:@"details_data"];
            [d1 setValue:@"Subject Line" forKey:@"subject_data"];   
            [temprecord addObject:d1];
            d1= nil;
            [d1 release];
        }

    }

    return temprecord;
    [temprecord release];
}

В чем проблема с этим кодом?Каждый раз, когда в массиве 9 записей, он просто заменяет все значение массива, а не только для определенного значения ключа.

1 Ответ

1 голос
/ 23 сентября 2011

Во-первых, неизменяемые коллекции Какао являются поточно-ориентированными.Их изменяемые аналоги не поточно-ориентированы.Создание вашего кода потокобезопасным, зависит от дизайна вашего приложения.Хорошая практика в многопоточной программе - использовать как можно больше неизменяемых данных.

Во-вторых, в:

NSMutableDictionary *holderKey = [[NSMutableDictionary alloc]initWithObjectsAndKeys:temprecord,[NSString stringWithFormat:@"%d",[casesListArray count]+1],nil];
[self.casesListArray addObject:holderKey];
[holderKey release];
holderKey =nil;
[temprecord removeAllObjects]; 

у вас есть следующее:

  • temprecord указывает на изменяемый массив
  • вы создаете изменяемый словарь с именем holderKey, который содержит один объект, а именно тот же temprecord, как указано выше
  • вы добавляете этот изменяемый словарь в self.casesListArray
  • вы освобождаете holderKey, который не освобождается, потому что он был добавлен в массив на предыдущем шаге
  • вы удаляете все объекты из temprecord.Поскольку temprecord - это тот же массив, что и в holderKey, в этом словаре также будет пустой массив.Поскольку holderKey было добавлено к self.casesListArray, соответствующий элемент массива является тем же словарем с тем же (теперь пустым) массивом.

Поскольку вы отправляете -removeAllObjects в temprecord во времяПри выполнении этого метода вы, вероятно, захотите вместо этого сохранить (изменяемую или неизменяемую) копию текущих значений массива:

NSMutableArray *tempRecordCopy = [temprecord mutableCopy];

NSMutableDictionary *holderKey = [[NSMutableDictionary alloc]initWithObjectsAndKeys:tempRecordCopy,[NSString stringWithFormat:@"%d",[casesListArray count]+1],nil];

[tempRecordCopy release];

Я не совсем уверен, нужно ли вам массив должен быть изменяемым.Если вы этого не сделаете, измените это значение на NSArray и -copy, и вы получите неизменную копию.

Наконец, вы используете странный шаблон, который приводит к утечкам памяти в настройке управляемой памяти,Например, в:

d1= nil;
[d1 release];

, поскольку вы присваиваете nil для d1, следующая инструкция, [d1 release], фактически является бездействующей.Это означает, что d1 больше не указывает на исходный объект, и этот объект не был освобожден.Не делай этого.Вместо этого:

[d1 release];

в большинстве случаев достаточно, и, если вам действительно нужно nil вывести переменную, сделайте это после выпуска:

[d1 release];
d1 = nil;

Редактировать: Еще одно примечание: в:

return temprecord;
[temprecord release];

temprecord не освобождается, потому что метод заканчивается при возврате.Эта попытка выпустить temprecord является недостижимым кодом и никогда не выполняется.Вместо этого вы хотите:

return [temprecord autorelease];

Другое редактирование: Обратите внимание, что -setObject:forKey: - это канонический метод добавления объектов в словарь.Вы используете -setValue:forKey:, который является методом KVC, который имеет своеобразное поведение при использовании в словарях.Если вы не знакомы с KVC, я предлагаю вам использовать -setObject:forKey:.

...