7

Я использую NSMutableDictionary и нажмите эту ошибку:«мутирует метод направлен непреложный объекта» несмотря объекта 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. Я оставил некоторые из прокомментированных строк в коде, чтобы показать вещи, которые я пробовал, и я ударил кирпичную стену. Я полагаю, что всегда могу создать новый словарь. Это предпочтительный способ сделать это?

ответ

9

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

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

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

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

для

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

Спасибо за предложение, но она по-прежнему дает мне ту же ошибку. Теперь у меня есть invoiceDictFromReq как свойство в .h и syntehsized в .m и установите его в данные из запроса json как self.invoiceDictFromReq = [словарь NSMutableDictionary ...] – okysabeni

+1

Извините, что я изменил свой ответ, это было не так. Посмотрите, есть ли у вас проблемы. Вам не нужно сохранять invoiceDictFromReq, потому что это локальная переменная, но удалить строку, которую вы создаете invoiceDictFromReq, в первый раз, потому что у вас есть утечка –

+0

:-). Когда я увидел: «Но ваша проблема в том, что вы создаете NSMutableDictionary, но вы устанавливаете self.invoiceDict словарь внутри вашего mutableDictionary, который не обязательно является mutableDictionary слишком« Я знал, что вы попали в него на месте. Так глупо со мной. Спасибо, что указали это. Я не должен был предполагать, что собственный парсер json возвращает NSMutableDictionary. Спасибо! – okysabeni

15

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

  • вариант использования NSJSONReadingMutableContainers

или

  • использования mutableCopy на результат
+1

Именно то, что я искал. Благодаря!!! – denikov

+0

Вам не нужно использовать mutableCopy, просто используйте результат.NSJSONReadingMutableContainers делает не только массивы и словари в результате изменяемого, но и сам результат. – gnasher729

 Смежные вопросы

  • Нет связанных вопросов^_^