Эта часть отказа сегментов кодов на мне, какая-либо идея, почему? 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];
}
То, что вы сказали
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];
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
Первый вызов replaceObjectAtIndex:
освободит старый объект ( tempA
), но это не должно вызвать ошибку сегмента. Как упоминал @Zoran, попробуйте зарегистрировать keepCount
для tempA и проверить его количество.
Также для замены элементов в массиве следует использовать exchangeObjectAtIndex: withObjectAtIndex
вместо replaceObjectAtIndex: withObject
. Поддерживается с iPhone 2.0.
Пожалуйста, прочитайте и поймите правила Cocoa о владении объектами. Обратите внимание, что вы не заявили о праве собственности на объекты, на которые ссылаются tempA и tempB, и поэтому вы должны принять во внимание следующее:
Полученный объект обычно гарантированно остается действительным в пределах метода, в котором он был получен... (хотя вы также должны быть осторожны, если вы изменяете объект, от которого вы получили другой объект). Этот метод также может безопасно вернуть объект своему инвокеру.
По сути, строка:
[allButtons replaceObjectAtIndex:a withObject:tempB];
может вызвать деаллокацию tempA. Это означает, что последующая строка заставит allButtons отправить сообщение retain недопустимому объекту, отсюда и ошибка seg. Чтобы устранить проблему, нужно сохранить tempA до замены и освободить его или автоматически освободить после.
NB следует забыть о подсчетах retain. Пока вы не знаете полностью реализацию всех объектов, которые касаются ваших объектов, вы не можете делать никаких предположений о том, каков счетчик retain объекта. Например, не существует правила, которое говорит, что реализация NSMutableArray будет сохранять свои элементы только один раз.