Как подкачать значения в NSMutableArray?

Эта часть отказа сегментов кодов на мне, какая-либо идея, почему? allButtons a NSMutableArray, это содержит 3 объекта, a=0, b=1, a и b int ввести

 if(a != -1 && b!= -1){
    //Swap index in "allButtons"
    id tempA = [allButtons objectAtIndex:a];
    id tempB = [allButtons objectAtIndex:b];
    [allButtons replaceObjectAtIndex:a withObject:tempB]; //Seg fault here?????
    [allButtons replaceObjectAtIndex:b withObject:tempA];
    needLoad = false;
    [self setUpButtons];
 }

Править:

 NSMutableArray *allButtons = //fetch the array from Coredata. This work since I display the data onto the screen, plus, [allButtons count] return 3, and a=0, b=1
 f(a != -1 && b!= -1){
    //Swap index in "allButtons"
    [allButtons exchangeObjectAtIndex:a withObjectAtIndex:b];
    needLoad = false;
    [self setUpButtons];
 }
9
задан Thang Pham 7 April 2010 в 06:04
поделиться

4 ответа

​​

То, что вы сказали

NSMutableArray *allbuttons = // something

, не означает, что это определенно NSMutableArray, это просто означает, что компилятор считает, что это будет NSMutableArray .

Если это из CoreData, вероятно, это просто NSArray , поэтому вызовы методов, которые вы пытаетесь использовать, не будут работать - вы получите нераспознанный селектор или что-то в этом роде.

Сначала вам нужно преобразовать его в изменяемый массив

NSArray *coreData = // core data call

// Create a mutable copy
// NB This means that you are now working on a copy, not the original :)
NSMutableArray *allButtons = [coreData mutableCopy];
11
ответ дан 4 December 2019 в 06:40
поделиться

tempA будет освобожден, когда вы вызовете первый replaceObjectAtIndex. Имейте это в виду при вызове этого... Я понятия не имею, почему освобождение tempA будет seg fault для вас, изучите, что делает его dealloc, возможно.

Проверьте счетчик retain для tempA, чтобы убедиться, что он действительно деаллоцирован (а не просто освобожден) вызовом replaceObjectAtIndex, как показано ниже:

id tempA = [allButtons objectAtIndex:a];
NSLog(@"retain count for tempA: %i", [tempA retainCount]);

Если на этом уровне вы видите счетчик retain, равный 1, то ваш объект tempA деаллоцируется вызовом replaceObjectAtIndex

2
ответ дан 4 December 2019 в 06:40
поделиться

Первый вызов replaceObjectAtIndex: освободит старый объект ( tempA ), но это не должно вызвать ошибку сегмента. Как упоминал @Zoran, попробуйте зарегистрировать keepCount для tempA и проверить его количество.

Также для замены элементов в массиве следует использовать exchangeObjectAtIndex: withObjectAtIndex вместо replaceObjectAtIndex: withObject . Поддерживается с iPhone 2.0.

22
ответ дан 4 December 2019 в 06:40
поделиться

Пожалуйста, прочитайте и поймите правила Cocoa о владении объектами. Обратите внимание, что вы не заявили о праве собственности на объекты, на которые ссылаются tempA и tempB, и поэтому вы должны принять во внимание следующее:

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

По сути, строка:

[allButtons replaceObjectAtIndex:a withObject:tempB];

может вызвать деаллокацию tempA. Это означает, что последующая строка заставит allButtons отправить сообщение retain недопустимому объекту, отсюда и ошибка seg. Чтобы устранить проблему, нужно сохранить tempA до замены и освободить его или автоматически освободить после.

NB следует забыть о подсчетах retain. Пока вы не знаете полностью реализацию всех объектов, которые касаются ваших объектов, вы не можете делать никаких предположений о том, каков счетчик retain объекта. Например, не существует правила, которое говорит, что реализация NSMutableArray будет сохранять свои элементы только один раз.

0
ответ дан 4 December 2019 в 06:40
поделиться