【问题标题】:iOS - PFQueryTableViewController - Delete Row crashesiOS - PFQueryTableViewController - 删除行崩溃
【发布时间】:2015-09-07 12:09:44
【问题描述】:

我正在使用带有本地数据存储的 PFQueryTableViewController。我想让用户使用以下代码从表中删除一个对象:

 // Override to support editing the table view.
     - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
     {
     if (editingStyle == UITableViewCellEditingStyleDelete) {
     // Delete the row from the data source

         PFObject * object = [self.objects objectAtIndex: indexPath.row];

         [object deleteInBackgroundWithBlock: ^ (BOOL succeeded, NSError * error) {
             [self loadObjects];
         }];

         [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

    }
     else if (editingStyle == UITableViewCellEditingStyleInsert) {
     // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
     }
  }

我明白了 *** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效更新:第 0 节中的行数无效。更新 (2) 后现有节中包含的行数必须等于行数更新前包含在该节中 (2),加上或减去从该节插入或删除的行数(0 插入,1 删除),加上或减去移入或移出该节的行数(0 移入, 0 移出)。'


我认为,这是在 PFQueryTableViewController 中使用的注释,但我找不到解决方案。 非常感谢。

【问题讨论】:

    标签: ios parse-platform


    【解决方案1】:

    当您从数组中删除对象时,您会更改 UITableView 的结构

    假设您从一个名为 objectsArray 的数组中的 100 个对象开始。

    • numberOfRowsInSection = 返回 objectsArray.count(即 100)
    • cellsForRowAtIndexPath = 100 个单元格,或者可以重复使用许多单元格来显示所有 100 个对象

    现在您刚刚从UITableView 中删除了一些行:[tableView deleteRowsAtIndexPaths:....] 假设您从objectsArray 中删除了3 行,这意味着您从UITableView 中删除了有形的行,因此UITableView 认为numberOfRows.. = 100 - 3。但事实并非如此,因为您还没有更新你的数组减去你刚刚删除的那 3 个对象。

    因此,您实际上是在删除这些有形的 3 行之前重新加载 tableView [self loadObjects],或者在您的情况下可能是因为 inBackground 部分。因此,换句话说,在您尝试对从 tableView 中删除的行进行动画处理之前再次重新加载 objectsArray。这不可能发生得足够快,特别是因为您将它放在异步回调中,出于性能考虑,您可能不应该这样做。所以简而言之,您需要在删除行之后更新您的数组,这样numberOfRowsInSection 将始终反映正确的对象数量

    如果您的数据很敏感并且您需要等待回调是否返回成功的deleteInBackground,那么您还应该在那里更新您的 tableView,因为您永远不知道该方法何时真正完成:

    ..deleteInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
        if (succeeded) {
          //get main thread
          [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
          [self loadObjects];
        } else {
          //error in deleting them 
        }
    }
    

    【讨论】:

    • 感谢您的回答。使用此代码,我得到其他错误: *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3347.44.2/UITableView.m:1623 我正在调查此错误的含义。你有什么想法吗。
    • 终于在这里找到了解决方案:stackoverflow.com/questions/31358082/…
    • 哦,拍摄。抱歉,我本来打算真正改变这一点,但被其他问题跟踪而忘了回来。对不起。该错误是给定的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-08
    相关资源
    最近更新 更多