NSMutableDictionary:将变异方法发送给不可变对象

下面的代码返回一个exception,当试图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]; 

NSUserDefaults返回不可变的对象,即使你把可变的对象。 您必须调用返回的值上的-mutableCopy来获取可变集合。

你不能只投了一个NSDictionaryNSMutableDictinary这根本不是如何投射工程。

NSUserDefualts调用NSUserDefaults实例本身的NSUserDefaults删除一个密钥。

如果你真的想要一个字典出于其他原因,那么你必须从dictionaryForKey获得的dictionaryForKey做一个mutableCopy

这是最终工作的代码,我使用了其他人提供的一些细节,但没有一个完全解释。

 - (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]; } 

如果你有错误NSMutableDictionary:mutating方法发送到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) } 

这工作对我来说!

[NSUserDefaults dictionaryForKey]返回一个不可变的字典( NSDictionary ),你不能强制它通过强制转换为NSMutableDictionary

相反,您必须使用mutableCopy创build可变字典,覆盖该元素,然后将字典重新分配回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"]; 

我发现同样的问题,并find解决scheme,希望它会帮助一些。

 arrayOfferId = defaults.objectForKey("offerId")?.mutableCopy() as! NSMutableArray 

NSUserDefaults返回不可变的对象,即使你把可变的对象。 您必须调用返回的值上的-mutableCopy来获取可变集合。 所以当你从NSUserDefault得到值使用mutableCopy()