1

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

__block NSMutableDictionary *tempDict = [NSMutableDictionary dictionaryWithCapacity:1]; 
__block NSUInteger idx; 
[_myArray enumerateObjectsUsingBlock:^(NSMutableDictionary* obj, 
                 NSUInteger indx, BOOL *stop) { 
    if (// some condition is met) { 
     tempDict = [obj mutableCopy]; 
     idx = indx; 
    } 
}]; 

[tempDict setObject:[NSNumber numberWithInt:thisQueryResults] forKey:@"resultsNum"]; 
[_myArray replaceObjectAtIndex:idx withObject:rowSelected]; 

это кажется слишком сложным (даже для языка, такого как obj-c) .. и поскольку он включает в себя два типа данных (NSMutableArray и NSMutableDictionary), похоже, я не могу их поместить в категорию .. совет?

обновление: один комментарий спросил, почему я создаю mutablecopy (в отличии от просто копии .. так как это копирование изменяемого объекта) ..

предположит, что я просто использовал копию .. если я положил перерыв на tempDict это то, что я получаю:

// tempDict = [obj copy] 
po tempDict 
$0 = 0x0b28cc10 <__NSArrayI 0xb28cc10>(
1 
) 

// tempDict = [obj mutableCopy] 
po tempDict 
$0 = 0x0b28cc10 <__NSArrayM 0xb28cc10>(//notice the M in __NSArrayM as opposed to I above 
1 
) 

в случае копия .. если я последую его с линии, как это: [tempDict SetObject: [NSNumber numberWithInt: thisQueryResults] forKey: @ "resultsNum"] ;

Я получаю эту ошибку:

[__NSDictionaryI setObject:forKey:]: unrecognized selector sent to instance 0xb245100 

Я получаю такие же выше ошибки с this кодом:

for (NSUInteger idx = 0; idx < [_myMutableArray count]; idx++) { 
    NSMutableDictionary* myMutableDict = _myMutableArray[idx]; 
    [myMutableDict setObject:obj forKey:key];   
} 

обновление 2: происхождения этой проблемы было инстанцирование не являющиеся изменяемые массивы и словари. Я новичок во всем новом obj-c literals, поэтому я не знал, что для создания NSMutableArray и NSDictionary вы должны сделать это соответственно:

[@[..] mutableCopy] 
[@{..} mutableCopy] 
+0

+1 для заметив это слишком сложно –

ответ

1

Так что в вашем случае я не совсем понимаю, почему вы вызываете tempDict = [obj mutableCopy]; когда из условий, которые вы пишете, словарь уже доступен для записи.

Вы можете использовать несколько трюков. Как и использование

for (NSUInteger idx = 0; idx < _myArray.count: idx++_ { 
    NSMutableDictionary *obj = _myArray[idx]; 

    // modify 
} 

Для NSDictionaries вы можете получить allKeys и перебрать эту копию. Это немного медленнее, чем использование быстрого перечисления, но все же быстрее, чем выполнение обходных решений, таких как целые числа бокса, которые нужно заменить позже :)

+0

я боюсь, что это не работает ..это то, что я пробовал: ' для (NSUInteger idx = 0; idx <[_rowsSelectedInfo count]; idx ++) { NSMutableDictionary * rowSelected = _rowsSelectedInfo [idx]; [rowSelected setObject: [NSNumber numberWithInt: thisQueryResults] forKey: @ "resultsNum"]; } '} Я получаю эту ошибку:' - [__ NSDictionaryI setObject: forKey:]: нераспознанный селектор, отправленный в экземпляр 0xb245100' по какой-то причине он переводит NSMutableDictioanry в __NSDictionaryI .. это та же ошибка, что и я, прежде чем я прибегнул к моему уродливому решению – abbood

+0

Затем вам нужно проверить свой массив - NSArray сохраняет и не копирует объекты, поэтому где-то в вашем коде вы добавляете не изменяемые структуры данных. Но вы всегда можете добавить mutableCopy - когда NSDictionary уже изменен, это просто сохраняет объект. – steipete

+0

wow man that's довольно глубокий .. правильный ответ получил – abbood

1

В вашем случае вы НЕ модифицируете массив вообще только словари внутри массива. Нет никаких ограничений на то, как вы изменяете объекты в массиве. Вот немного эквивалентного кода:

for (NSMutableDictionary *dict in _myArray) { 
    if (someCondition) 
     [dict setObject:[NSNumber numberWithInt:thisQueryResults] forKey:@"resultsNum"] 
} 

У вас возникнет проблема, если вам абсолютно необходимо заменить объект в вашем массиве. В этом случае, если массив не огромен, я бы предложил такое же, как @Markus. Итерации над копией и изменение оригинала.

+0

обновил мой вопрос, чтобы ответить на ваш ответ – abbood

+0

Причина, по которой вы получаете эту ошибку, состоит в том, что, хотя вы, что у вас есть изменяемые словари в вашем массиве, они на самом деле не являются. Посмотрите на точку в коде, где вы изначально создаете этот массив и добавляете словари к ним, и убедитесь, что они являются изменяемыми словарями. Подсказка: '@ {}' создаст NSDictionary, а не NSMutableDictionary. Вы могли бы сделать '[@ {} mutableCopy]' хотя. – aLevelOfIndirection

+0

+1 для трюка 'mutableCopy' – abbood

0

Может быть, вы можете использовать KVC и сделать:

NSArray<NSMutableDictionary *> *result = [[_myArray filteredArrayUsingPredicate:[NSPredicate withFormat:@"{YOUR CONDITION}"]] valueForKey:@"mutableCopy"]; 

 Смежные вопросы

  • Нет связанных вопросов^_^