以下代码在尝试removeObjectForKey时返回一个异常,并显示以下错误消息“mutating method sent to immutable object”
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];
答案 0 :(得分:55)
NSUserDefaults返回不可变对象,即使你输入了可变对象。您必须对返回的值调用-mutableCopy以获取可变集合。
答案 1 :(得分:3)
你不能仅仅将NSDictionary
投射到NSMutableDictinary
,而不是投射的方式。
从NSUserDefualts
实例本身的removeObjectForKey
电话NSUserDefaults
移除密钥。
如果您确实因某些其他原因需要字典,那么您必须从mutableCopy
获得的字典中创建dictionaryForKey
。
答案 2 :(得分:3)
这是最终有效的代码,我使用了上面其他人提供的一些细节,但没有一个完全解释过。
- (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's saved
[[NSUserDefaults standardUserDefaults] synchronize];
}
答案 3 :(得分:3)
如果您有错误NSMutableDictionary:在Swift中发送到不可变对象的mutating方法,请执行以下步骤:
这是因为你已经为NSMutableArray分配了一个NSUserDefault,当你拿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)
}
这项工作对我来说!!!
答案 4 :(得分:3)
我发现了同样的问题,发现解决方案希望它能帮到某个人。
arrayOfferId = defaults.objectForKey("offerId")?.mutableCopy() as! NSMutableArray
NSUserDefaults返回不可变对象,即使你输入了可变对象。您必须在返回的值上调用-mutableCopy以获取可变集合。所以当你从NSUserDefault获得价值时,请使用mutableCopy()
答案 5 :(得分:2)
[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"];