-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object Return then Get from NSUserDefaults

Multi tool use
-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object Return then Get from NSUserDefaults
The following code is returning an exception with the following error message and My Application Crashed, in my code all data store in NSMutableDictionary
and then store in NSUserDefaults
After get the data and assign global NSMutableDictionary
and i will try to update data in NSMutableDictionary
app crash and showing error
NSMutableDictionary
NSUserDefaults
NSMutableDictionary
NSMutableDictionary
-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary * cacheUploadDataDic = [[defaults objectForKey:@"SalaryIncomeData"] mutableCopy];
mutableCopy
As said by @CharlesSrstka This line of code shouldn't crash. Where does your crash happen? And
mutableCopy
make mutable only the "top level", not the sub-objects. It's not recursive.– Larme
Jul 2 at 15:21
mutableCopy
3 Answers
3
Exactly, it crashes with mutable type issue, all the objects you retrieved from user defaults are inmutable, it uses the plist file to serialized the data list to file, check the plist programming guide about the supported types.
You shall regard the user defaults as a simple plist file storage wrapper.
Use NSMutableDictionary's 'initWithDictionary:' method instead.
Since an answer to the question in my comment does not appear to be forthcoming, I'm just going to go out on a limb and make the guess that your cacheUploadDataDic
dictionary contains some more NSDictionary
objects inside of it, and that your crash is occurring when you try to mutate one of those dictionaries. This fails because mutableCopy
performs a shallow copy; only the dictionary object itself is copied, and all of the objects inside the dictionary, including any additional dictionaries, remain their original immutable selves.
cacheUploadDataDic
NSDictionary
mutableCopy
You can fix this by making a deep copy of the dictionary instead. There are a few ways to do this, but the simplest is probably to use the CFPropertyListCreateDeepCopy
function. Unfortunately, we have to do some bridging, since this API is only available at the CoreFoundation level, the reason for which is one of those eternal mysteries.
CFPropertyListCreateDeepCopy
Anyway, do something like this:
NSDictionary *dict = [[NSUserDefaults standardUserDefaults] objectForKey:@"SomeKey"];
NSMutableDictionary *mutableDict = CFBridgingRelease(
CFPropertyListCreateDeepCopy(kCFAllocatorDefault,
(__bridge CFDictionaryRef)dict,
kCFPropertyListMutableContainersAndLeaves)
);
You will now be able to mutate the contents of mutableDict
to your heart's content.
mutableDict
Follow your code, there shows no problem.
Then if possible, you can check the class of cacheUploadDataDic
before update data and after NSMutableDictionary * cacheUploadDataDic = [[defaults objectForKey:@"SalaryIncomeData"] mutableCopy]
.
If there are one NSMutableDictionary
and the other is NSDictionary
then you must change cacheUploadDataDic
at other line.
if you can't find out where you change the object,you can try KVO.
cacheUploadDataDic
NSMutableDictionary * cacheUploadDataDic = [[defaults objectForKey:@"SalaryIncomeData"] mutableCopy]
NSMutableDictionary
NSDictionary
cacheUploadDataDic
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Can you show the line that's causing the crash? Are you getting the crash while trying to mutate one of the objects inside the dictionary?
mutableCopy
only makes the dictionary mutable; the objects inside would still be immutable.– Charles Srstka
Jul 2 at 15:10