NCSFDictionary, Метод мутации отправлен в неизменный объект - PullRequest
0 голосов
/ 01 декабря 2010

Я только начал прыгать в сферу Objective-C и постепенно получаю все это. Я работал над разархивированием файла, который был NSMutableArray, а затем инициализировал в моей модели с этим массивом. Массив заполнен различными NSMutableDicationary's. Из того, что я видел, он добавит эти словари как неизменяемые, поэтому я скопировал обычные и поместил их в изменяемый и удалил старый. Похоже, что это решение подходит для всех случаев, кроме самого первого.

Я в недоумении, почему это будет работать для всех, кроме первого.

Вот как я все это инициализирую

-(id) initWithList:(NSMutableArray *)savedList
{
    self = [super init];
    if (self)
    {
        int size=0;
        serverList=[[NSMutableArray alloc] initWithArray:savedList copyItems:YES];
        size=[serverList count];
        for(int i=0;i<size;i++)
        {
            loginList=[NSMutableDictionary dictionaryWithDictionary:[serverList objectAtIndex:i]];
            [serverList addObject:loginList];
            [serverList removeObjectAtIndex:i];
        }
    }
    return self;
} 

Вот код, который выдает ошибку. Значение считывается из флажка в табличном представлении и передается здесь для изменения значения.

-(void)setMount:(int)row value:(NSNumber*)boolAsNumber
{
    [[serverList objectAtIndex:row] setObject:boolAsNumber forKey:@"mountshare"];
}

Вот ошибка, которая появляется, когда я пытаюсь изменить первый элемент

2010-12-01 13:38:54.445 Network Share[35992:a0f] *** -[NSCFDictionary setObject:forKey:]: mutating method sent to immutable object

Спасибо за вашу помощь. Если есть лучший способ, пожалуйста, дайте мне знать.

Ответы [ 2 ]

3 голосов
/ 02 декабря 2010

Этот код цикла неверен:

    size=[serverList count];
    for(int i=0;i<size;i++)
    {

        loginList=[NSMutableDictionary dictionaryWithDictionary:[serverList objectAtIndex:i]];
        [serverList addObject:loginList];
        [serverList removeObjectAtIndex:i];
    }

При удалении объекта массив перенумеровывается.После того, как вы обработали 1-й объект с индексом 0, исходный 2-й объект становится 1-м объектом с индексом 0, но i теперь установлен в индекс 1, где находится исходный 3-й объект!Это означает, что вы обрабатываете только альтернативные элементы из исходного массива, а 2-й, 4-й и т. Д. Элементы никогда не меняются местами, и поэтому вы получаете ошибки, которые вы видите.

Один из способов решения этой проблемы -заменить "i" в вызовах objectAtIndex: и removeObjectAtIndex: на "0", чтобы вы всегда убирали элементы из передней части массива.

Альтернативным решением будет созданиеразделите массив newServerList и вставьте в него новые объекты.В конце цикла освободите старый serverList и установите для переменной значение newServerList.

1 голос
/ 02 декабря 2010

Ваши индексы испорчены.Как только вы удалите объект с индексом 0, следующий займет его место, и вы никогда не замените его, потому что затем вы продолжите с индексом 1.

{immutable0, immutable1}

i = 0: 

addObject:
{immutable0, immutable1, mutable0}

removeObjectAtIndex:
{immutable1, mutable0}

i = 1:

addObject:
{immutable0, mutable0, mutable02}

removeObjectAtIndex:
{immutable0, mutable02}

-> все еще получил неизменяемыйтам.Не забывайте никогда не удалять объекты из изменяемого массива, по которому вы одновременно проходите цикл.

Вы можете немного сжать код:

NSMutableArray *serverList = [NSMutableArray arrayWithCapacity:[savedList count]];
for (NSDictionary *dictionary in savedList)
{
  mutable = [dictionary mutableCopy];
  [serverList addObject:mutable];
  [mutable release];
}

Не имеет отношения к вашей проблеме: аргумент очевиденнеправильно (NSMutableArray), если вы ожидаете неизменный массив там;и если вы создаете свой serverList таким образом, вам не нужно глубокое копирование (copyItems: YES).

...