7

sto usando NSMutableDictionary e ha colpito questo errore:"mutazione metodo inviati oggetto immutabile", nonostante oggetto essendo NSMutableDictionary

'NSInternalInconsistencyException', reason: '-[__NSCFDictionary removeObjectForKey:]: mutating method sent to immutable object' 

Ecco il codice:

// Turn the JSON strings/data into objects 
    NSError *error; 
    NSMutableDictionary *invoiceDictFromReq = [[NSMutableDictionary alloc] init]; 
// invoiceDictFromReq = (NSMutableDictionary *)[NSJSONSerialization JSONObjectWithData:[request responseData] options:kNilOptions error:&error]; 
    invoiceDictFromReq = [NSMutableDictionary dictionaryWithDictionary:[NSJSONSerialization JSONObjectWithData:[request responseData] options:kNilOptions error:&error]]; 

NSLog(@"invoiceDictFromReq count: %i, key: %@, value: %@", [invoiceDictFromReq count], [invoiceDictFromReq allKeys], [invoiceDictFromReq allValues]); 

// Get values and keys from JSON response 
self.invoiceDict = [invoiceDictFromReq objectForKey:@"invoice"]; 
NSNumber *invoiceAmount = [self.invoiceDict objectForKey:@"amount"]; 
NSNumber *invoiceId = [self.invoiceDict objectForKey:@"id"]; 
NSNumber *invoiceNumber = [self.invoiceDict objectForKey:@"number"]; 
NSNumber *checkoutStarted = [self.invoiceDict objectForKey:@"checkoutStarted"]; 
NSNumber *checkoutCompleted = [self.invoiceDict objectForKey:@"checkoutCompleted"]; 
NSLog(@"amount: %@, id: %@, number: %@, started: %@, completed: %@", invoiceAmount, invoiceId, invoiceNumber, checkoutStarted, checkoutCompleted); 

Tutti i log della console indicano che il i dati vanno bene. Questo è dove le cose cominciano a crollare. passo la proprietà invoiceDict all'altro controller della vista:

// Pass the invoice to checkoutViewController 
[checkoutViewController setInvoiceDict:self.invoiceDict]; 

In CheckoutViewController.m:

// Change invoice checkoutCompleted to true 
// [self.invoiceDict removeObjectForKey:@"checkoutCompleted"]; 
    [self.invoiceDict setObject:[NSNumber numberWithBool:YES] forKey:@"checkoutCompleted"]; 

L'errore è a [self.invoiceDict setObject...]. Mi sono assicurato che tutti i dizionari che uso siano NSMutableDictionary. Ho lasciato alcune delle righe commentate nel codice per mostrare le cose che ho provato e ho colpito un muro di mattoni. Suppongo di poter sempre creare un nuovo dizionario. È il modo migliore per farlo?

risposta

9

Si sta allocando un dizionario in invoiceDictFromReq e successivamente si sta creando un altro dizionario, si sta creando una perdita di memoria lì. Elimina la linea

NSMutableDictionary *invoiceDictFromReq = [[NSMutableDictionary alloc] init]; 

Ma il problema è che si sta creando un NSMutableDictionary ma si sta impostando per self.invoiceDict un dizionario all'interno del vostro mutableDictionary, che non è necessariamente una mutableDictionary troppo. Modificare la riga

self.invoiceDict = [invoiceDictFromReq objectForKey:@"invoice"]; 

per

self.invoiceDict = [NSMutableDictionary dictionaryWithDictionary:[invoiceDictFromReq objectForKey:@"invoice"]]; 
+0

Grazie per il suggerimento, ma ancora mi dà lo stesso errore Ora ho invoiceDictFromReq come una proprietà in .h e syntehsized in .m e lo impostai ai dati dalla richiesta json come self.invoiceDictFromReq = [NSMutableDictionary dictionary ...] – okysabeni

+1

Scusa se ho cambiato la mia risposta, non era quello. Vedi se hai ancora il problema. Non è necessario mantenere invoiceDictFromReq perché è una variabile locale, ma eliminare la riga che si crea invoiceDictFromReq per la prima volta perché c'è una perdita lì –

+0

:-). Quando ho visto, "Ma il tuo problema è che stai creando un NSMutableDictionary ma stai impostando self.invoiceDict un dizionario all'interno del tuo mutableDictionary, che non è necessariamente anche un mutevoleDictionary" Sapevo che l'avresti colpito immediatamente. Così sciocco da parte mia. Grazie per segnalarlo. Non avrei dovuto presumere che il parser json nativo restituisse NSMutableDictionary. Grazie mille! – okysabeni

15

NSJSONSerialization restituisce oggetti immutabili per impostazione predefinita. Ecco come ottenere dizionario mutabile dal parser:

  • opzione uso NSJSONReadingMutableContainers

o

  • uso mutableCopy sul risultato
+1

Esattamente quello che stavo cercando. Grazie!!! – denikov

+0

Non è necessario utilizzare mutableCopy, basta usare il risultato.NSJSONReadingMutableContainers rende non solo modificabili matrici e dizionari all'interno del risultato, ma anche il risultato stesso. – gnasher729

Problemi correlati