- [__ NSCFDictionary setObject: forKey:]: мутирующий метод, отправленный неизменяемому объекту. Return затем Get from NSUserDefaults. - PullRequest
0 голосов
/ 02 июля 2018

Следующий код возвращает исключение со следующим сообщением об ошибке и My Application Crashed, в моем коде все данные сохраняются в NSMutableDictionary, а затем сохраняются в NSUserDefaults После получения данных и назначения глобального NSMutableDictionary, и я попытаюсь обновить данные в NSMutableDictionary сбой приложения и показывает ошибку

- [__NSCFDictionary setObject: forKey:]: метод мутирования, отправленный неизменяемому объекту

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary * cacheUploadDataDic = [[defaults objectForKey:@"SalaryIncomeData"] mutableCopy];

Ответы [ 3 ]

0 голосов
/ 03 июля 2018

Точно, происходит сбой с проблемой изменчивого типа, все объекты, которые вы извлекли из пользовательских значений по умолчанию, являются неизменяемыми, он использует файл plist для сериализации списка данных в файл, ознакомьтесь с руководством по программированию plist относительно поддерживаемых типов.

Вы будете считать пользовательские настройки по умолчанию простой оберткой для хранения файлов plist.

Используйте взамен метод initWithDictionary: NSMutableDictionary.

0 голосов
/ 03 июля 2018

Поскольку ответ на вопрос в моем комментарии, похоже, не ожидается, я просто собираюсь выйти на конечность и предположить, что ваш словарь cacheUploadDataDic содержит еще несколько NSDictionary объектов внутри него и что ваш сбой происходит, когда вы пытаетесь изменить один из этих словарей. Это терпит неудачу, потому что mutableCopy выполняет поверхностное копирование; копируется только сам объект словаря, и все объекты внутри словаря, включая любые дополнительные словари, остаются их исходными неизменяемыми "я" .

Вы можете исправить это, сделав вместо этого глубокую копию словаря. Есть несколько способов сделать это, но, возможно, самый простой - использовать функцию CFPropertyListCreateDeepCopy. К сожалению, нам нужно соединиться, так как этот API доступен только на уровне CoreFoundation, причина которого - одна из тех вечных загадок.

В любом случае, сделайте что-то вроде этого:

NSDictionary *dict = [[NSUserDefaults standardUserDefaults] objectForKey:@"SomeKey"];

NSMutableDictionary *mutableDict = CFBridgingRelease(
    CFPropertyListCreateDeepCopy(kCFAllocatorDefault,
                                 (__bridge CFDictionaryRef)dict,
                                 kCFPropertyListMutableContainersAndLeaves)
);

Теперь вы сможете изменять содержание mutableDict до уровня своего сердца.

0 голосов
/ 02 июля 2018

Следуйте вашему коду, там проблем нет.
Затем, если возможно, вы можете проверить класс cacheUploadDataDic до обновления данных и после NSMutableDictionary * cacheUploadDataDic = [[defaults objectForKey:@"SalaryIncomeData"] mutableCopy].
Если есть один NSMutableDictionary, а другой - NSDictionary, вы должны изменить cacheUploadDataDic в другой строке.
если вы не можете узнать, где вы меняете объект, вы можете попробовать KVO.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...