2010-04-07 4 views
9

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

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]; 
} 

EDIT:

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]; 
} 
+0

Это может быть полезно, чтобы получить возможность отправлять фактическое сообщение об ошибке, если это возможно. Вероятно, было бы полезно опубликовать объявление класса, чтобы мы могли видеть, является ли allButtons свойством, и если да, то какова его семантика управления памятью и т. Д. – jlehr

ответ

11

Просто потому, что вы сказали

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]; 
+0

ty, которые исправляют проблему. –

+1

Или просто NSMutableArray * allButtons = [coreData mutablecopy]; –

2

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

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

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

Если вы видите сохранить счетчик 1 на этом уровне , то ваш объект tempA в настоящее время dealloc-е изд по вызову replaceObjectAtIndex

+0

'recountCount' return back 3. –

+0

Вы вызываете это из основная нить или вторичная резьба? Если вы вызываете его из вторичного потока, вы создали пул авто-релизов? –

22

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

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

+0

Я пытаюсь «exchangeObjectAtIndex: withObjectAtIndex», и это то, что я получил «Завершение приложения из-за неперехваченного исключения» NSInvalidArgumentException », причина:« *** - [_ PFArray exchangeObjectAtIndex: withObjectAtIndex:]: нераспознанный селектор, отправленный экземпляру 0x3a35a30''. BTW, 'recountCount' верните назад 3. –

+0

какую версию iPhone SDK вы используете? Также, пожалуйста, напишите код, в котором вы создаете 'NSMutableArray', и используя' exchangeObject..' – Anurag

+0

Я просто редактирую свой код. TYVM –

0

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

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

В принципе, линия:

[allButtons replaceObjectAtIndex:a withObject:tempB]; 

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

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

0

Используйте этот метод передачи индекса appropritate

exchangeObjectAtIndex:withObjectAtIndex: 
Смежные вопросы