"Mutation method sent to an immutable object", although the object is an NSMutableDictionary

I use NSMutableDictionary and hit this error:

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

Here is the code:

  // 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); 

All console logs indicate that the data is in order. Here, everything begins to collapse. I pass the invoiceDict property to the following view controller:

 // 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"]; 

Error in [self.invoiceDict setObject...] . I made sure that all the dictionaries that I use are NSMutableDictionary . I left some of the commented lines in the code to show the things I tried and I hit a brick wall. I believe that I can always create a new dictionary. Is this the preferred way to do this?

+7
source share
2 answers

You assign a dictionary to invoiceDictFromReq, and then you create another dictionary, you create a memory leak there. Delete row

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

But your problem is that you create an NSMutableDictionary, but you install a self.invoiceDict dictionary inside your mutableDictionary, which is also not necessarily mutableDictionary. Change the line

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

for

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

NSJSONSerialization returns immutable objects by default. Here's how to get a mutable dictionary from the parser:

  • use the NSJSONReadingMutableContainers option

or

  • use mutableCopy for result
+15
source

All Articles