0
votes

In short after getting arrays from NSUserDefaults I'm getting Mutating method sent to immutable object error when I'm trying to change NSMutableArray value;

generalDone[self.todoTableView.selectedRow] = 1

When saving to NSUserDefaults I'm adding all NSMutableArrays to one NSMutableArray. Like;

var saveArray:NSMutableArray = NSMutableArray()
saveArray.removeAllObjects()
saveArray.add(generalTodos)
..
..
..
saveArray.add(generalDone)
UserDefaults.standard.set(saveArray, forKey: "test3")

But when I'm getting arrays from NSUserDefault I'm sure it is a mutableCopy().

if UserDefaults.standard.value(forKey: "test3") != nil {
    saveArray = UserDefaults.standard.mutableArrayValue(forKey: "test3").mutableCopy() as! NSMutableArray

    generalTodos = saveArray[0] as! NSMutableArray
    generalDone = saveArray[1] as! NSMutableArray
}

Still getting same error. Maybe silly idea but I'm thinking arrays in saveArrays still not mutable. But don't know how to manage them. What's your ideas?

Trying to learn swift. Please be polite. -_-

1
May I ask why you are using NSArray / NSMutableArray at all? They are Objective-C Cocoa classes. You should be using Swift arrays. They make things much easier. - matt
"but I'm thinking arrays in saveArrays still not mutable" Good thinking. You may be making a mutable copy of saveArrays but that doesn't make the arrays inside it mutable. - matt
Also I would advise against saving an array of arrays into NSUserDefaults. Just save generalTodos as its own array with its own key. - matt
Finally, note please that UserDefaults is very picky about what you can save into it. You can save an array of strings, but not, say, an array of ToDoObjects. So watch out for that. - matt

1 Answers

1
votes

If you are going to use Objective-C NSMutableArray, saying as! NSMutableArray won't make one; the way to make an NSMutableArray is to say

let mutableArray = NSMutableArray(array: otherArray)

But you should be using Swift arrays, not Objective-C NSArray/NSMutableArray. To make a Swift array mutable, declare it with var, not let. For example, if generalTodos is an array of strings, you could say

var generalTodos = [String]()