7

Używam NSMutableDictionary i uderzyć ten błąd:„mutowania metoda wysłany do niezmiennego obiektu” pomimo obiektu NSMutableDictionary

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

Oto kod:

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

Wszystkie dzienniki konsoli wskazują, że dane są w porządku. Tu zaczynają się załamywać sprawy. mijam właściwość invoiceDict do następnego kontrolera widoku:

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

W CheckoutViewController.m:

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

Błąd znajduje się na [self.invoiceDict setObject...]. Upewniłem się, że wszystkie używane przeze mnie słowniki to NSMutableDictionary. Zostawiłem niektóre z zakomentowanych linii kodu, aby pokazać rzeczy, które wypróbowałem i uderzyłem w mur. Przypuszczam, że zawsze mogę stworzyć nowy słownik. Czy jest to najlepszy sposób na zrobienie tego?

Odpowiedz

9

Przydzielasz słownik w invoiceDictFromReq, a następnie tworzysz inny słownik, tworząc tam wyciek pamięci. Usuń linię

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

Ale problem jest to, że tworzysz NSMutableDictionary ale ustawiasz do self.invoiceDict słownika wewnątrz mutableDictionary, że niekoniecznie jest mutableDictionary też. Zmień linię

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

dla

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

Dzięki za sugestię, ale nadal daje mi ten sam błąd. Teraz mam invoiceDictFromReq jako właściwość w .h i syntehsized w .m i ustawić go na dane z żądania json jako self.invoiceDictFromReq = [Słownik NSMutableDictionary ...] – okysabeni

+1

Niestety, zmieniłem odpowiedź, to nie było to. Sprawdź, czy nadal masz problem. Nie musisz zachowywać invoiceDictFromReq, ponieważ jest to zmienna lokalna, ale usuń linię, którą stworzyłeś invoiceDictFromReq po raz pierwszy, ponieważ masz przeciek tam –

+0

:-). Kiedy zobaczyłem, "Ale twoim problemem jest to, że tworzysz NSMutableDictionary, ale ustawiasz na self.invoiceDict słownik wewnątrz mutableDictionary, który niekoniecznie jest mutableDictionary też" Wiedziałem, że trafiłeś to na miejscu. Tak głupi ode mnie. Dziękuję za wskazanie. Nie powinienem zakładać, że macierzysty parser JSON zwraca NSMutableDictionary. Dzięki wielkie! – okysabeni

15

NSJSONSerialization zwroty niezmiennych obiektów domyślnie. Oto jak uzyskać zmienny słownika z parsera:

  • opcja użycie NSJSONReadingMutableContainers

lub

  • użytku mutableCopy na wynik
+1

Dokładnie to, czego szukałem. Dzięki!!! – denikov

+0

Nie trzeba używać polecenia mutableCopy, wystarczy użyć wyniku.NSJSONReadingMutableContainers sprawia, że ​​nie tylko tablice i słowniki w wynikach są zmienne, ale także sam wynik. – gnasher729

Powiązane problemy