【问题标题】:Delete UITableViewCell row with NSMutableArray throws exception使用 NSMutableArray 删除 UITableViewCell 行会引发异常
【发布时间】:2016-10-13 07:57:53
【问题描述】:

我有一个表格视图,每个单元格内的数据是一个 NSMutableArray。每次向左滑动并按下删除按钮时,我都想删除表格视图的一行。然而,使用 NSMutableArray 很困难。每次输入代码toDoItems.removeObjectAtIndex(indexPath.row) 时,我都会得到一个 Sigabrt。

我得到的错误是

以 NSException 'NSInternalInconsistencyException' 类型的未捕获异常终止,原因:'-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object'

对这个问题有帮助吗?

这是与问题相关的代码。

包含 toDoItems 的 ViewDidLoad 代码:

let userDefaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()

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

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

我的 NSMutableArray 变量

var toDoItems:NSMutableArray! = NSMutableArray()

我的 commitEditingStyle 函数:

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();


    }

我的 numberOfRowsInSection 函数:

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


        return toDoItems.count
    }

我的 cellForRowAtIndexPath 函数:

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



}

这是错误

MyPlanner[12373:461118] * 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object” * 首先抛出调用栈: ( 0 CoreFoundation 0x0000000109df3d85 异常预处理 + 165 1 libobjc.A.dylib 0x0000000109867deb objc_exception_throw + 48 2 核心基础 0x0000000109df3cbd +[NSException raise:format:] + 205 3 核心基础 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 发送事件:] + 849 17 UIKit 0x000000010aad3dc6 -[UIApplication 发送事件:] + 263 18 UIKit 0x000000010aaad553 _UIApplicationHandleEventQueue + 6660 19 核心基础 0x0000000109d19301 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17 20 核心基础 0x0000000109d0f22c __CFRunLoopDoSources0 + 556 21 核心基础 0x0000000109d0e6e3 __CFRunLoopRun + 867 22 核心基础 0x0000000109d0e0f8 CFRunLoopRunSpecific + 488 23 图形服务 0x000000010ec78ad2 GSEventRunModal + 161 24 UIKit 0x000000010aab2f09 UIApplicationMain + 171 25 MyPlanner 0x00000001092134fd 主 + 125 26 libdyld.dylib 0x000000010d43d92d 开始 + 1 ) libc++abi.dylib:以 NSException 类型的未捕获异常终止 (lldb)

这是我在 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()

【问题讨论】:

  • 与 NSException 关联的文本是什么?为什么您的删除代码无法处理信息来自filteredAppleProducts 数组的情况?
  • 请检查我创建的完整错误的编辑
  • @Paulw11 我取出了过滤的AppleProducts,但它仍然无法正常工作
  • 您是否将任何代码行分配给DoItems 作为普通数组(不可变)?请显示您启动 toDoItems 的代码。
  • @SonLe 我没有任何其他包含 toDoItems 的代码,我初始化 toDoItems 的地方是显示的第一行代码 var toDoItems: NSMutableArray! = NSMutableArray()

标签: swift uitableview nsmutablearray nsuserdefaults


【解决方案1】:

NSUserDefaults objectForKey 将始终返回不可变对象。简单地向下转换它不会使其可变。您需要从返回的不可变数组中创建一个可变数组:

let userDefaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()

if let itemListFromUserDefaults = userDefaults.objectForKey("itemList") as? NSArray
    toDoItems = itemListFromUserDefaults.mutableCopy()
}

【讨论】:

  • 你能告诉我应该把那行代码放在哪里吗?
  • 上面的代码从NSUserDefaults检索数组; viewDidLoad
  • 此外,由于您使用空的NSMutableArray 初始化toDoItems,因此无需将其设为隐式展开的可选;你不需要:NSMutableArray!
  • 还有一个问题,当我杀死应用程序并再次运行它时,我删除的单元格仍然显示,我希望它们被删除而不显示。
  • 更改数组后需要将数组写回用户默认值
猜你喜欢
  • 2014-02-14
  • 2010-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 1970-01-01
  • 2013-05-20
  • 1970-01-01
相关资源
最近更新 更多