NSMutableDictionary: метод мутирования, отправленный на неизменяемый объект
Следующий код возвращает исключение со следующим сообщением об ошибке "Метод мутирования, отправленный на неизменяемый объект" при попытке удалитьObjectForKey
NSMutableDictionary * storedIpDictionary = (NSMutableDictionary*)[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"dictDeviceIp"];
NSString *key = self.currentDeviceNameText.text;
NSString *ipAddressTemp = [storedIpDictionary objectForKey:key];
[storedIpDictionary removeObjectForKey:key]; <----Crashes here
storedIpDictionary[key] = ipAddressTemp;
Не уверен, в чем проблема, возможно, из-за извлечения словаря из NSUserDefaults.
Однако следующий код работает без каких-либо проблем.
NSMutableDictionary * storedIpDictionary = (NSMutableDictionary*)[[NSUserDefaults standardUserDefaults] dictionaryForKey:@"dictDeviceIp"];
[storedIpDictionary removeAllObjects];
Ответы
Ответ 1
Это код, который в конечном итоге сработал, я использовал некоторые детали, предоставленные другими выше, но ни один из них не был полностью объяснен.
- (void)cleanDictionary
{
NSMutableDictionary * storedIpDictionary = [[[NSUserDefaults standardUserDefaults] objectForKey: @"dictDeviceIp"] mutableCopy];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@"dictDeviceIp"];
NSString *oldKey = self.currentDeviceNameText.text;
NSString *newKey = self.deviceNameChangeText.text;
NSString *ipAddressTemp = [storedIpDictionary objectForKey:oldKey];
// Make some change to the structure
[storedIpDictionary removeObjectForKey:oldKey]; // Remove object
storedIpDictionary[newKey] = ipAddressTemp; // Add object with new key
// Add it the whole thing back into NSUserDefaults
[[NSUserDefaults standardUserDefaults] setObject:storedIpDictionary forKey:@"dictDeviceIp"];
// Synchronize to ensure it saved
[[NSUserDefaults standardUserDefaults] synchronize];
}
Ответ 2
NSUserDefaults возвращает неизменяемые объекты, даже если вы введете изменчивые. Вы должны вызвать -mutableCopy для возвращаемого значения, чтобы получить измененную коллекцию.
Ответ 3
Вы не можете просто отличить NSDictionary
до NSMutableDictinary
отнюдь не о том, как работает кастинг.
удалить ключ из NSUserDefualts
вызова removeObjectForKey
в самом экземпляре NSUserDefaults
.
Если вам действительно нужен словарь по какой-то другой причине, тогда вы должны сделать mutableCopy
из словаря, полученного с помощью dictionaryForKey
.
Ответ 4
если у вас есть ошибка NSMutableDictionary: метод мутирования, отправленный в неизменяемый объект в Swift, выполните этот шаг:
Это связано с тем, что вы назначили NSUserDefault для NSMutableArray, когда вы берете что-то NSUserDefault, он возвращает NSArray, а не NSMutableArray, поэтому в этом случае вам нужно использовать вспомогательный NSMutableArray.
см. для Swift:
var Products:NSMutableArray = NSMutableArray()
override func viewDidAppear(animated: Bool) {
if let Produtos = NSUserDefaults.standardUserDefaults().valueForKey("Produtos") {
Products = Produtos as! NSMutableArray
}
}
func InsertProducts(productCode:String){
//COPY Products Atual for auxMutable
var auxMutable = Products.mutableCopy()
//Add object in auxMutable
auxMutable.addObjectsFromArray([productCode])
//in line back data to Array Products and make cast to NSMutableArray
Products = auxMutable as! NSMutableArray
//Refresh Data of NSUserDefaults
NSUserDefaults.standardUserDefaults().setObject(Products, forKey: "Produtos")
}
@IBAction func Bt_New_Product(sender: AnyObject) {
var ProductName:String = TXT_NameProduct.text
InsertProducts(ProductName)
}
Эта работа для меня!!!
Ответ 5
[NSUserDefaults dictionaryForKey]
возвращает неизменный словарь (NSDictionary
), и вы не можете заставить его быть изменяемым, отбросив его на NSMutableDictionary
.
Вместо этого вы должны создать изменяемый словарь с помощью mutableCopy
, перезаписать элемент и затем повторно назначить словарь обратно в NSUserDefaults
:
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary *storedIpDictionary = [[userDefaults dictionaryForKey:@"dictDeviceIp"] mutableCopy];
NSString *key = self.currentDeviceNameText.text;
NSString *ipAddressTemp = [storedIpDictionary objectForKey:key];
// Don't need this line
//[storedIpDictionary removeObjectForKey:key];
storedIpDictionary[key] = ipAddressTemp;
[userDefaults setObject:storedIpDictionary
forKey:@"dictDeviceIp"];
Ответ 6
Я нашел ту же проблему и нашел решение, надеюсь, что это поможет кому-то.
arrayOfferId = defaults.objectForKey("offerId")?.mutableCopy() as! NSMutableArray
NSUserDefaults возвращает неизменяемые объекты, даже если вы введете изменчивые. Вы должны вызвать -mutableCopy для возвращаемого значения, чтобы получить изменчивую коллекцию. поэтому, когда вы получаете значение из NSUserDefault, используйте mutableCopy()