【问题标题】:NSMutableDictionary: mutating method sent to immutable objectNSMutableDictionary:发送到不可变对象的变异方法
【发布时间】:2014-08-04 19:30:54
【问题描述】:

以下代码在尝试 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];

【问题讨论】:

  • 消息说什么?你猜这意味着什么?什么是不可变对象?将 NSDictionary 转换为 NSMutableDictionary 指针会使字典可变吗?
  • 我不确定它为什么是 NSDictionary,因为 NSUserDefault 被定义为 NSMutableDictionary - @property (nonatomic, retain) NSMutableDictionary* dictDeviceIp;
  • 不知道为什么这个问题被否决了,这解决了我的问题。
  • 谢谢鲍勃,人们投反对票的速度太快了,通常在阅读整个问题之前就完成了。无论如何,很高兴看到这篇文章恢复了积极状态!尽管有所有这些反对票,这意味着很多人得到了帮助。

标签: ios objective-c nsuserdefaults nsmutabledictionary mutable


【解决方案1】:

NSUserDefaults 返回不可变对象,即使你放入了可变对象。您必须对返回的值调用 -mutableCopy 以获取可变集合。

【讨论】:

    【解决方案2】:

    您不能只将NSDictionary 投射到NSMutableDictinary,这根本不是投射的工作原理。

    要从NSUserDefualts 中删除密钥,请在NSUserDefaults 实例本身上调用removeObjectForKey

    如果你真的因为其他原因需要字典,那么你必须从dictionaryForKey获得的字典中创建一个mutableCopy

    【讨论】:

      【解决方案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];
      }
      

      【讨论】:

        【解决方案4】:

        如果您遇到错误 NSMutableDictionary: mutating method sent to immutable object in Swift,请执行以下步骤:

        这是因为你已经为 NSMutableArray 分配了一个 NSUserDefault,当你使用 NSUserDefault 时它会返回一个 NSArray 而不是 NSMutableArray,所以在这种情况下你必须使用一个 NSMutableArray Auxiliary。

        看 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】:

          我发现了同样的问题并找到了解决方案,希望对某人有所帮助。

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

          NSUserDefaults 返回不可变对象,即使你放入了可变对象。您必须对返回的值调用 -mutableCopy 以获取可变集合。因此,当您从 NSUserDefault 获得价值时,请使用 mutableCopy()

          【讨论】:

            【解决方案6】:

            [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"];
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-08-13
              • 2016-11-17
              • 1970-01-01
              • 2012-08-22
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多