#objective-c #xcode #nsmutablearray #nsmutabledictionary
#objective-c #xcode #nsmutablearray #nsmutabledictionary
Вопрос:
Мне нужно добавить 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
}
Я не знаю, как заменить последний добавленный объект.
Комментарии:
1. попробуйте
[NSDictionary alloc] init]
в цикле for, а затем добавьте данные.2. В цикл? Но я завершаю цикл. Я создал новый NSMutableDictionary для каждого элемента, а затем добавил в другую структуру? @NiravKotecha
3. да, в цикл.
4. когда вы выполняете инициализацию из цикла, каждый раз он переходит во внутренний цикл, и ключ остается тем же, поэтому он перезаписывается новым значением. если вы запустите цикл, он создаст новый.
5. Спасибо. Это были мои проблемы. Мне нужно создать NSMutableDictionary в цикле. @NiravKotecha
Ответ №1:
попробуйте [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];
}
Ответ №2:
Добавление словаря в массив не копирует словарь. Он хранит ссылку на объект (словарь) в массиве, поэтому ссылка на идентичный словарь добавляется каждый раз.
Перезапись содержимого словаря изменяет идентичный словарь, который хранится в массиве несколько раз.
Вы должны каждый раз создавать новый словарь. Нет причин создавать изменяемый объект.
Ответ №3:
Как указывалось в комментариях, ваша проблема связана с ссылочной семантикой коллекций 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]
}
];
}
Вы можете обнаружить, что использование литералов словаря (и массива) помогает вам избежать ошибок выделения и создания изменяемых структур, когда они не требуются. HTH