0

I have a tableview and the data inside each cell is an NSMutableArray. I want to delete a row of the tableview each time I swipe left and press the delete button. However it is difficult with an NSMutableArray. I get a Sigabrt everytime I input the code toDoItems.removeObjectAtIndex(indexPath.row).

The error I get is

Terminating with uncaught exception of type NSException 'NSInternalInconsistencyException', reason: '-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object'

Any help on this problem?

Here is code relating to the problem.

ViewDidLoad code containing toDoItems:

let userDefaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()

        let itemListFromUserDefaults:NSMutableArray? = userDefaults.objectForKey("itemList") as? NSMutableArray

        if ((itemListFromUserDefaults) != nil){
            toDoItems = itemListFromUserDefaults!
        }

My NSMutableArray variable

var toDoItems:NSMutableArray! = NSMutableArray()

My commitEditingStyle function:

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath){

    if(editingStyle == UITableViewCellEditingStyle.Delete){


        //This code gives me the error and Sigabrt
        toDoItems.removeObjectAtIndex(indexPath.row)



        tbl?.reloadData();


    }

My numberOfRowsInSection function:

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{


        return toDoItems.count
    }

My cellForRowAtIndexPath function:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->
    UITableViewCell{

        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! TableView

            let toDoItem:NSDictionary = toDoItems.objectAtIndex(indexPath.row) as! NSDictionary
            cell.lbl.text = toDoItem.objectForKey("itemTitel") as? String

            return cell



}

Here is the error

MyPlanner[12373:461118] * Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object' * First throw call stack: ( 0 CoreFoundation 0x0000000109df3d85 exceptionPreprocess + 165 1 libobjc.A.dylib 0x0000000109867deb objc_exception_throw + 48 2 CoreFoundation 0x0000000109df3cbd +[NSException raise:format:] + 205 3 CoreFoundation 0x0000000109de9dae -[__NSCFArray removeObjectAtIndex:] + 94 4 MyPlanner 0x0000000109210c53 _TTSf4dg_n_g_n___TFC9MyPlanner14ViewController9tableViewfTCSo11UITableView18commitEditingStyleOSC27UITableViewCellEditingStyle17forRowAtIndexPathCSo11NSIndexPath_T_ + 131 5 MyPlanner 0x000000010920fc3d _TToFC9MyPlanner14ViewController9tableViewfTCSo11UITableView18commitEditingStyleOSC27UITableViewCellEditingStyle17forRowAtIndexPathCSo11NSIndexPath_T_ + 61 6 UIKit 0x000000010ac124c0 -[UITableView animateDeletionOfRowWithCell:] + 205 7 UIKit 0x000000010abe7a3e __52-[UITableView _swipeActionButtonsForRowAtIndexPath:]_block_invoke + 80 8 UIKit 0x000000010ac13eaa -[UITableView _actionButton:pushedInCell:] + 172 9 UIKit 0x000000010ae3aae6 -[UITableViewCell _actionButtonPushed:] + 82 10 UIKit 0x000000010aab4a8d -[UIApplication sendAction:to:from:forEvent:] + 92 11 UIKit 0x000000010ac27e67 -[UIControl sendAction:to:forEvent:] + 67 12 UIKit 0x000000010ac28143 -[UIControl _sendActionsForEvents:withEvent:] + 327 13 UIKit 0x000000010ac27263 -[UIControl touchesEnded:withEvent:] + 601 14 UIKit 0x000000010af9cc52 _UIGestureRecognizerUpdate + 10279 15 UIKit 0x000000010ab2748e -[UIWindow _sendGesturesForEvent:] + 1137 16 UIKit 0x000000010ab286c4 -[UIWindow sendEvent:] + 849 17 UIKit 0x000000010aad3dc6 -[UIApplication sendEvent:] + 263 18 UIKit 0x000000010aaad553 _UIApplicationHandleEventQueue + 6660 19 CoreFoundation 0x0000000109d19301 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17 20 CoreFoundation 0x0000000109d0f22c __CFRunLoopDoSources0 + 556 21 CoreFoundation 0x0000000109d0e6e3 __CFRunLoopRun + 867 22 CoreFoundation 0x0000000109d0e0f8 CFRunLoopRunSpecific + 488 23 GraphicsServices 0x000000010ec78ad2 GSEventRunModal + 161 24 UIKit 0x000000010aab2f09 UIApplicationMain + 171 25 MyPlanner 0x00000001092134fd main + 125 26 libdyld.dylib 0x000000010d43d92d start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)

Here is the code where I put in the information(add items) in toDoItems.

@IBAction func ClickedforSelection(sender: AnyObject) {

    if delegate != nil {
        let information : NSString = txt1.text!

        delegate!.userDidEntredInformation(information)

    }

    let userDefaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()

    var itemList:NSMutableArray? = userDefaults.objectForKey("itemList") as? NSMutableArray

    let dataSet:NSMutableDictionary = NSMutableDictionary()
    dataSet.setObject(txt.text!, forKey: "itemTitel")


    if ((itemList) != nil){ // data already available
        let newMutableList:NSMutableArray = NSMutableArray();

        for dict:AnyObject in itemList!{
            newMutableList.addObject(dict as! NSDictionary)
        }

        userDefaults.removeObjectForKey("itemList")
        newMutableList.addObject(dataSet)
        userDefaults.setObject(newMutableList, forKey: "itemList")


    }else{ // This is the first todo item in the list
        userDefaults.removeObjectForKey("itemList")
        itemList = NSMutableArray()
        itemList!.addObject(dataSet)
        userDefaults.setObject(itemList, forKey: "itemList")
    }

    userDefaults.synchronize()
11
  • What is the text associated with the NSException? Why does your delete code not handle the case where the information is coming from the filteredAppleProducts array? Commented Jun 13, 2016 at 1:25
  • Please check the edit I created with the full error Commented Jun 13, 2016 at 1:51
  • @Paulw11 I took out filteredAppleProducts however it still is not working Commented Jun 13, 2016 at 1:55
  • Are there any line of code that you assign toDoItems as an normal array (not mutable)? Please show the code you init the toDoItems. Commented Jun 13, 2016 at 1:59
  • @SonLe I don't have any other codes that contain toDoItems, and where I init toDoItems is the first line of code shown var toDoItems: NSMutableArray! = NSMutableArray() Commented Jun 13, 2016 at 2:05

1 Answer 1

2

NSUserDefaults objectForKey will always return immutable objects. Simply down casting it won't make it mutable. You need to create a mutable array from the immutable array that is returned:

let userDefaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()

if let itemListFromUserDefaults = userDefaults.objectForKey("itemList") as? NSArray
    toDoItems = itemListFromUserDefaults.mutableCopy()
}
Sign up to request clarification or add additional context in comments.

6 Comments

Can you please tell me where I should put that line of code.
Wherever you have the code above that is retrieving the array from NSUserDefaults; viewDidLoad
Also, since you are initialising toDoItems with an empty NSMutableArray there is no need to make it an implicitly unwrapped optional; you don't need the :NSMutableArray!
there is one more problem, when I kill the app and run it again, the cells that I had deleted are still showing, where I want them to just be deleted and not showing.
You need to write the array back to user defaults after you change it
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.