2010-04-07 9 views
9

Questo pezzo di codice mi disturba, qualche idea del perché? allButtons è un NSMutableArray, contiene 3 oggetti, a=0, b=1, a e b sono int tipoCome scambiare valori in 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

Può essere utile per inviare il messaggio di errore effettivo, se possibile. Sarebbe probabilmente anche utile pubblicare la dichiarazione della classe in modo che possiamo vedere se allButtons è una proprietà e, in tal caso, quali sono le semantiche di gestione della memoria, ecc. – jlehr

risposta

11

Solo perché avete detto

NSMutableArray *allbuttons = // something 

non significa che essa è sicuramente un NSMutableArray, significa solo che il compilatore pensa che sarà un NSMutableArray.

Se è da CoreData, probabilmente è solo un NSArray in modo che il metodo chiama che si sta cercando non funziona - si otterrà selettore unrecongnised o qualcosa di simile.

Si dovrà convertirlo in un array di mutabile prima

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 che risolve il problema. –

+1

Oppure solo NSMutableArray * allButtons = [mutablecopy coreData]; –

2

tempA sta per essere rilasciato quando si chiama il primo replaceObjectAtIndex. Tienilo a mente quando chiami questo ... Non ho idea del motivo per cui il rilascio di tempA segga un errore per te, esamina cosa potrebbe fare il suo dealloc.

Controllare il conteggio di tempA mantenere per verificare che sia davvero dealloc-ed (non semplicemente rilasciato) dalla chiamata a replaceObjectAtIndex in questo modo:

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

Se si vede un conteggio di conservare 1 a questo livello , allora il vostro oggetto tempA è essere dealloc-ed dalla chiamata a replaceObjectAtIndex

+0

'recountCount' return 3. –

+0

Stai chiamando questo dal filetto principale o una filettatura secondaria? Se lo chiami da un thread secondario, hai creato un pool di rilascio automatico? –

22

la prima chiamata a replaceObjectAtIndex: rilascerà il vecchio oggetto (tempA), ma che non dovrebbe causare un guasto seg. Come @Zoran menzionato prova a registrare lo retainCount per tempA e verificarne il conteggio.

Anche per lo scambio di elementi in un array, è necessario utilizzare exchangeObjectAtIndex:withObjectAtIndex anziché replaceObjectAtIndex:withObject. È supportato da iPhone 2.0.

+0

Provo 'exchangeObjectAtIndex: withObjectAtIndex' e questo è quello che ho ottenuto' Terminazione dell'app a causa dell'eccezione non rilevata 'NSInvalidArgumentException', motivo: '*** - [_ PFArray exchangeObjectAtIndex: withObjectAtIndex:]: selettore non riconosciuto inviato all'istanza 0x3a35a30''. BTW, 'recountCount' return back 3. –

+0

quale versione di iPhone SDK stai usando? Inoltre, si prega di inserire il codice in cui si sta creando il 'NSMutableArray', e usando' exchangeObject..' – Anurag

+0

Ho appena modificato il mio codice. TYVM –

0

Leggere e comprendere le regole Cocoa su object ownership. Si noti che non è stato rivendicato la proprietà sugli oggetti a cui fa riferimento Tempa e tempB e si deve quindi prestare attenzione quanto segue:

A ha ricevuto oggetto viene normalmente garantito per rimanere valida all'interno del metodo che è stato ricevuto in ... (anche se devi anche fare attenzione se modifichi un oggetto dal quale hai ricevuto un altro oggetto). Questo metodo può anche restituire l'oggetto al suo invocatore in modo sicuro.

Fondamentalmente, la linea:

[allButtons replaceObjectAtIndex:a withObject:tempB]; 

Può provocare Tempa da deallocato. Ciò significa che la riga successiva farà sì che allButton invii un messaggio di conservazione a un oggetto non valido, quindi l'errore seg. Per risolvere il problema, è necessario conservare tempA prima dello scambio e rilasciarlo o autorizzarlo dopo.

NB è consigliabile dimenticare i conteggi di mantenimento. A meno che non si sia pienamente consapevoli dell'implementazione di tutti gli oggetti che toccano gli oggetti, non è possibile formulare alcuna ipotesi su quale sia il numero di conservazione di un oggetto. Ad esempio, non esiste una regola che affermi che l'implementazione di NSMutableArray conserverà sempre i suoi elementi solo una volta.

0

Utilizzare questo metodo passa l'indice appropritate

exchangeObjectAtIndex:withObjectAtIndex: 
Problemi correlati