错误:replaceObjectAtIndex:withObject:]:发送到不可变对象

时间:2015-12-21 15:49:39

标签: ios

我的应用程序因标题中提到的异常而崩溃。请在下面找到我的解释:

尝试在我的TableViewController中使用NSUserDefaults存储数组值,如下所示:

func didDismissContentViewController(controller:ContentViewController,pageIndex:Int) { //You're passed in the contentViewController here, use relevant data to update your model. NSLog("Inside delegate method ..\n") var currentIdx = pageIndex

    NSLog("Value of index edited \(pageIndex)")
    NSLog("Current edited value is : \(controller.myTextView.text)")

    **pageContent.replaceObjectAtIndex(pageIndex, withObject: controller.myTextView.text)**

**//pageCotent is defined as an NSMutableArray only...**

    NSUserDefaults.standardUserDefaults().setObject(pageContent as NSMutableArray, forKey: "PageValues")
    NSUserDefaults.standardUserDefaults().synchronize()
}
Retrieval is done as under : if var storedPageContent = NSUserDefaults.standardUserDefaults().objectForKey("PageValues") as? NSMutableArray{ pageContent = storedPageContent

虽然我能够在各自的页面中存储,检索和显示更新的页面值,但是在tableviewcontroller和内容视图控制器之间来回转换会引发以下错误:

015-12-21 00:51:46.592 PageApp[3943:203948] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray replaceObjectAtIndex:withObject:]: mutating method sent to immutable object' * First throw call stack:

我尝试将商店注释到NSUserDefault,并且应用程序不会崩溃,而使用NSUserDefault存储值会导致这种情况发生,因此当我将其存储在NSUserDefaults中然后检索并将其分配给NSUserDefaults时会出现错误阵列。

对此有任何帮助将不胜感激。Exchange data between uitah

5 个答案:

答案 0 :(得分:1)

我认为问题是即使您将从NSUserDefaults检索到的值分配给NSMutableArray,但实际上并没有像您预期的那样创建NSMutableArray。您可以尝试使用从NSMutableArray获取的对象初始化新的NSUserDefaults吗? 在Objective-C中,它就像

NSMutableArray *pageContent = [[NSMutableArray alloc] initWithObjects:object1,nil];

其中object1是从NSUserDefaults获取的值。对不起,我不知道斯威夫特

答案 1 :(得分:1)

NSUserDefaults返回的数组是不可变的,因此您需要制作数组的可变副本,然后在修改后再在NSUserDefaults中重新设置数组。

我不太了解Swift给你一个代码示例,但这是在Objective-C中完成的:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefauts];
NSMutableArray *pageContent = [[userDefaults objectForKey:@"PageValues"] mutableCopy];
[pageContent replaceObjectAtIndex:pageIndex withObject:controller.myTextView.text];
[userDefaults setObject:pageContent forKey:@"PageValues"];

答案 2 :(得分:1)

我昨天遇到了完全相同的问题。显然,如果使用NSUserDefaults获取数组对象,即使将其指定为NSMutableArray,它也会像NSArray一样。

所以我解决这个问题的方法是使用这种方式(Objective-C)。一旦我将它传递给另一个NSMutableArray,我就能够从中添加/删除对象。

NSArray *favArrayTemp = [[NSUserDefaults standardUserDefaults] objectForKey:@"MyFavServers"];
NSMutableArray favArray = [[NSMutableArray alloc] initWithArray:favArrayTemp];

答案 3 :(得分:1)

使用Swift原生类型。

将从NSUserDefaults检索到的类型转换为本地Swift集合类型var,然后它是可变的。

var pageContent = [String]()
...

let userDefaults = NSUserDefaults.standardUserDefauts()
pageContent = userDefaults["PageValues"] as! [String]

替换也很容易。

pageContent[pageIndex] = controller.myTextView.text

附注:从NSUserDefaults读取值时强制解包假设键/值对已正确注册。然后展开是安全的。

答案 4 :(得分:0)

感谢您的回复。我按照你的建议做了改动,但它确实奏效了。让我在下面分享:

//正如您所提到的,由于NSUserDefault总是需要一个NS阵列,我在下面进行了存储:

NSLog("我在bactktomonths .. \ n")

//定义一个NS Array,将Mutable数组复制到Immutable数组         var storedArray = NSArray()

    storedArray     = pageArray!

    NSUserDefaults.standardUserDefaults().setObject(storedArray , forKey:    "PageValues")
    NSUserDefaults.standardUserDefaults().synchronize()
}

//检索。

if(NSUserDefaults.standardUserDefaults()。objectForKey(" PageValues")!= nil){

        pageContent = NSUserDefaults.standardUserDefaults().objectForKey("PageValues")?.mutableCopy() as NSMutableArray

//我不确定如果我需要执行以下代码,但我已经按照建议离开了它,它目前正常工作!  NSUserDefaults.standardUserDefaults()。setObject(pageContent,forKey:" PageValues")

由于