«Метод мутации отправлен в неизменяемый объект», несмотря на то, что объект является NSMutableDictionary - PullRequest
7 голосов
/ 28 ноября 2011

Я использую NSMutableDictionary и нажимаю эту ошибку:

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

Вот код:

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

Все журналы консоли показывают, что данные в порядке.Здесь вещи начинают разрушаться.Я передаю свойство invoiceDict следующему контроллеру представления:

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

В CheckoutViewController.m:

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

Ошибка в [self.invoiceDict setObject...].Я убедился, что все словари, которые я использую, NSMutableDictionary.Я оставил некоторые закомментированные строки в коде, чтобы показать то, что я пробовал, и ударился о кирпичную стену.Я полагаю, я всегда могу создать новый словарь.Это предпочтительный способ сделать это?

Ответы [ 2 ]

15 голосов
/ 11 марта 2013

NSJSONSerialization возвращает неизменные объекты по умолчанию.Вот как получить изменяемый словарь из парсера:

  • использовать опцию NSJSONReadingMutableContainers

или

  • использовать mutableCopy нарезультат
9 голосов
/ 28 ноября 2011

Вы выделяете словарь в invoiceDictFromReq, а затем вы создаете другой словарь, вы создаете утечку памяти там. Удалить строку

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

Но ваша проблема в том, что вы создаете NSMutableDictionary, но вы устанавливаете для self.invoiceDict словарь внутри mutableDictionary, который также не обязательно является mutableDictionary. Изменить строку

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

для

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