Когда я пытаюсь добавить NSDictionary в NSMutableArray, я не могу заменить последний добавленный объект - PullRequest
0 голосов
/ 27 марта 2019

Мне нужно добавить NSDictionary в NSMutableArray.

Сначала я создал NSMutableDictionary со значением ключа из другой структуры, например:

for (NSString *key in selectedFiltersByUser) {
    [filters_data setObject:key forKey:@"key"];
    [filters_data setObject:selectedFiltersByUser[key] forKey:@"value"];

    // Added filter selected id's into Array for all query_params
    [query_params addObject:filters_data];
}

selectedFiltersByUser - это словарь, подобный этому:

{
category_id = "XXX";
sort = "last_updated_asc";
status = "rejected_by_seller";
}

идля каждого ключа: значение в этом словаре я создаю новый NSMutableDictionary, подобный этому:

{
  key: category_id,
  value: XXX
}

И этот новый NSMutableDictionary добавляется в NSMutableArray, как это:

    for (NSString *key in selectedFiltersByUser) {
    [filters_data setObject:key forKey:@"key"];
    [filters_data setObject:selectedFiltersByUser[key] forKey:@"value"];

    // Added filter selected id's into Array for all query_params
    [query_params addObject:filters_data];
}

Но когдадобавив NSMutableDictionary в NSMutableArray, он не заменяет последний объект, и я получаю это в query_params:

    {
       key: category_id,
       value: XXX
   },
   {
    key: category_id,
    value: XXX
   },
   {
    key: category_id,
    value: XXX
   }

Мне нужно это:

{
       key: category_id,
       value: XXX
   },
   {
    key: sort,
    value: last_updated_asc
   },
   {
    key: status,
    value: rejected_by_seller
   }

Я незнать, как заменить последний добавленный объект.

Ответы [ 3 ]

1 голос
/ 27 марта 2019

попробуйте [NSMutableDictionary alloc] init] в цикле for, а затем добавьте данные.

, потому что, когда вы init выходите из цикла, каждый раз, когда он переходит во внутренний цикл, а ключ один и тот же, он перезаписываетс новым значением.если вы init попадете в цикл, он создаст новый.

for (NSString *key in selectedFiltersByUser) {

    //INIT HERE YOUR DICTIONARY
    NSMutableDictionary *filters_data = [NSMutableDictionary alloc] init];

    [filters_data setObject:key forKey:@"key"];
    [filters_data setObject:selectedFiltersByUser[key] forKey:@"value"];

    // Added filter selected id's into Array for all query_params
    [query_params addObject:filters_data];
}
0 голосов
/ 28 марта 2019

Как отмечается в комментариях, ваша проблема связана с ссылочной семантикой коллекций Objective-C, то есть они содержат ссылки на существующие объекты и , а не их копии. Поэтому, если вы добавляете один и тот же NSMutableDictionary несколько раз к NSMutableArray, как ваш код, вы в конечном итоге получаете, что каждый элемент массива является ссылкой на один и тот же словарь. Простое исправление, которое уже было предложено, заключается в размещении словаря внутри цикла:

for (NSString *key in selectedFiltersByUser)
{
   NSMutableDictionary *filters_date = [NSMutableDictionary new];
   [filters_data setObject:key forKey:@"key"];
   [filters_data setObject:selectedFiltersByUser[key] forKey:@"value"];
   [query_params addObject:filters_data];
}

Однако вы можете сделать это проще и избежать проблемы в целом. Вы уже индексируете selectedFiltersByUser, вы также можете индексировать filters_data аналогичным образом, давая вам:

for (NSString *key in selectedFiltersByUser)
{
   NSMutableDictionary *filters_date = [NSMutableDictionary new];
   filters_data[@"key"] = key;
   filters_data[@"value"] = selectedFiltersByUser[key];
   [query_params addObject:filters_data];
}

но это все еще оставляет вас с распределением, которое вы можете удалить, используя литерал словаря :

for (NSString *key in selectedFiltersByUser)
{
   NSDictionary *filters_date
      = @{ @"key": key,
           @"value": selectedFiltersByUser[key]
         };
   [query_params addObject:filters_data];
}

Теперь выделение обрабатывается компилятором автоматически, и вы получаете NSDictionary. Последний вариант - сбросить filters_date всего:

for (NSString *key in selectedFiltersByUser)
{
   [query_params addObject:@{ @"key": key,
                              @"value": selectedFiltersByUser[key]
                            }
   ];
}

Вы можете обнаружить, что использование литералов словаря (и массива) помогает избежать ошибок размещения и создания изменяемых структур, когда они не требуются. НТН

0 голосов
/ 27 марта 2019

Добавление словаря в массив не копирует словарь.В нем хранится ссылка на объект (словарь) массива, поэтому ссылка на идентичный словарь добавляется каждый раз.

Перезапись содержимого словаря приводит к изменению идентичного словаря, который хранится в массиве несколько раз.

Каждый раз необходимо создавать новый словарь.Нет причин для создания изменчивого.

...