次のコードは、removeObjectForKeyを実行しようとすると、「不変オブジェクトに送信されたメソッドの変更」というエラーメッセージとともに例外を返します。
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];
これは最終的に機能したコードであり、上記の他の人から提供された詳細の一部を使用しましたが、完全に説明されたものはありませんでした。
- (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];
}
NSUserDefaultsは、可変オブジェクトを配置した場合でも、不変オブジェクトを返します。可変コレクションを取得するには、戻り値に対して-mutableCopyを呼び出す必要があります。
NSDictionary
をNSMutableDictinary
にキャストすることはできませんが、キャストの仕組みはまったく異なります。
NSUserDefualts
からキーを削除するには、removeObjectForKey
インスタンス自体でNSUserDefaults
を呼び出します。
他の理由で本当に辞書が必要な場合は、mutableCopy
によって取得された辞書からdictionaryForKey
を作成する必要があります。
私は同じ問題を見つけ、解決策を見つけました。それが誰かを助けることを願っています。
arrayOfferId = defaults.objectForKey("offerId")?.mutableCopy() as! NSMutableArray
NSUserDefaultsは、可変オブジェクトを配置した場合でも、不変オブジェクトを返します。可変コレクションを取得するには、戻り値に対して-mutableCopyを呼び出す必要があります。したがって、NSUserDefaultから値を取得するときは、mutableCopy()を使用します。
エラーNSMutableDictionary:Swiftの不変オブジェクトに送信された変更メソッドがある場合は、次の手順を実行します。
これは、NSUserDefaultをNSMutableArrayに割り当てたためです。NSUserDefaultを取得すると、NSMutableArrayではなくNSArrayが返されるため、この場合はNSMutableArrayAuxiliaryを使用する必要があります。
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
を使用して可変ディクショナリを作成し、要素を上書きしてから、ディクショナリを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"];