Iphone 重新加载RowsatindExpaths:withRowAnimation:使我的应用程序崩溃

Iphone 重新加载RowsatindExpaths:withRowAnimation:使我的应用程序崩溃,iphone,uitableview,crash,Iphone,Uitableview,Crash,我的UITableView遇到了一个奇怪的问题:我使用reloadRowsAtIndexPaths:withRowAnimation:来重新加载一些特定的行,但应用程序崩溃时出现了一个看似无关的异常:NSInternalInconsistencyException-尝试删除比节中存在的行更多的行 我的代码如下所示: [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRo

我的UITableView遇到了一个奇怪的问题:我使用
reloadRowsAtIndexPaths:withRowAnimation:
来重新加载一些特定的行,但应用程序崩溃时出现了一个看似无关的异常:NSInternalInconsistencyException-尝试删除比节中存在的行更多的行

我的代码如下所示:

[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
当我用一个简单的
reloadData
替换
reloadrowsatinexpaths:withRowAnimation:
消息时,它工作得非常好


有什么想法吗?

我认为以下代码可能会起作用:

[self.tableView beginUpdates];

[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];

[self.tableView endUpdates];

问题是,您可能已经更改了表的大小。例如,您已经为表视图添加或删除了一些源数据

在这种情况下,当您调用
reloadData
时,您的表将完全重新加载,包括节的大小和节的数量

但是,当调用
reloadRowsAtIndexPaths:withRowAnimation:
时,表视图的参数不会被重新加载。这会导致下一个问题:当您试图重新加载某些单元格表时,请检查表视图的大小,并查看它是否已更改。这导致了一场车祸。仅当您不想重新加载单元格视图(例如,标签已更改或希望更改其大小)时,才能使用此方法

现在,如果要从表视图中删除/添加单元格,应使用下一种方法:

  • 通过调用
    UITableView
  • 通知有关使用方法插入新行的信息
    -(void)insertRowsAtIndexPaths:(NSArray*)indexPaths with rowanimation:(UITableViewRowAnimation)animation
  • 使用方法
    -(void)deleteRowsAtIndexPaths:(NSArray*)InExpaths with RowAnimation:(UITableViewRowAnimation)animation删除行的相关信息
  • 通过调用
    UITableView
  • 希望对您有所帮助

    这已经很旧了。不要使用。 当我调用
    reloadRowsAtIndexPaths…
    将单元格更改为包含
    UITextField
    的编辑单元格时,我遇到了这个问题。错误告诉我正在删除表中的所有行。为了解决这个问题,我删除了:

    [self.tableView beginUpdates];
    NSArray *reloadIndexPath = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:count inSection:section]];
    [self.tableView reloadRowsAtIndexPaths:reloadIndexPath withRowAnimation:UITableViewRowAnimationFade];  
    [self.tableView endUpdates];
    
    并将其替换为

    [self.tableView reloadData];
    

    我也有同样的问题。就我而言;只有当另一个视图控制器弹出/推送到现有的表视图控制器上,然后调用[self.tableView reloadRowsAtIndexPaths]函数时,才会发生这种情况

    reloadRowsAtIndexPaths调用在一个表视图中隐藏/显示不同的行,该表视图有30多个视觉上复杂的行。当我试图解决这个问题时,我发现如果我稍微滚动一下table view应用程序并没有崩溃。如果我不隐藏一个单元格,它也不会崩溃(通过返回0作为高度)

    为了解决这个问题,我只需更改“(CGFloat)tableView:(UITableView*)tableView heightforrowatinexpath:(nsindepath*)indepath”函数,并返回至少0.01作为行高

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    ....
    return rowModel.height + 0.01; // Add 0.01 to work around the crash issue.
    }
    

    它为我解决了这个问题。

    我遇到了这个问题,它是由一个块调用reloadRowsAtIndexPaths:withRowAnimation:和一个并行线程调用reloadData引起的。 崩溃是由于重新加载rowsatindexpaths导致的:尽管我检查了numberofrowsinssection和numberOfSections,但通过rowsanimation找到了一个空表

    我的态度是,我真的不在乎它是否会导致异常。作为应用程序的用户,我可以忍受一种视觉上的腐败,而不是让整个应用程序崩溃

    以下是我的解决方案,我很高兴与大家分享,并欢迎建设性的批评。如果有更好的解决方案我很想听听

    - (void) safeCellUpdate: (NSUInteger) section withRow : (NSUInteger) row {
        // It's important to invoke reloadRowsAtIndexPaths implementation on main thread, as it wont work on non-UI thread
        dispatch_async(dispatch_get_main_queue(), ^{
            NSUInteger lastSection = [self.tableView numberOfSections];
            if (lastSection == 0) {
                return;
            }
            lastSection -= 1;
            if (section > lastSection) {
                return;
            }
            NSUInteger lastRowNumber = [self.tableView numberOfRowsInSection:section];
            if (lastRowNumber == 0) {
                return;
            }
            lastRowNumber -= 1;
            if (row > lastRowNumber) {
                return;
            }
            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
            @try {
                if ([[self.tableView indexPathsForVisibleRows] indexOfObject:indexPath] == NSNotFound) {
                    // Cells not visible can be ignored
                    return;
                }
                [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
            }
    
            @catch ( NSException *e ) {
                // Don't really care if it doesn't work.
                // It's just to refresh the view and if an exception occurs it's most likely that that is what's happening in parallel.
                // Nothing needs done
                return;
            }
        });
    }
    
    经过多次尝试,我发现“reloadRowsAtIndexPaths”只能在某些地方使用,只要更改单元格内容而不是插入或删除单元格。没有任何地方可以使用它,即使你把它包起来

    [self beginUpdates];
    //reloadRowsAtIndexPaths
    [self endUpdates];
    
    我发现可以使用它的地方有:

    -(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(nsindepath*)indepath
    -(iAction)取消通知列表:(UIStoryboardSegue*)发件人

    从其他地方进行的任何尝试,如从“viewDidLoad”或“ViewDidDisplay”调用它,要么不会生效(对于已加载的单元格,我的意思是,重载将不会生效),要么导致异常


    因此,请尝试仅在这些位置使用“reloadRowsAtIndexPaths”。

    应用程序崩溃,因为您对tableView进行了一些更改。您已经在tableView中添加或删除了一些行。因此,当视图控制器向模型控制器类请求数据时,IndExpath中存在不匹配。因为修改后索引路径发生了变化

    因此,要么你干脆取消通话

    [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
    
    或者用

    [self.tableView reloadData];
    

    调用reloadData会检查您的节数、每个节中的行数,然后重新加载整个内容。

    在重新加载之前,您应该检查单元格的可见性。以下是Swift 3代码:

            let indexPath = IndexPath(row: offset, section: 0)
            let isVisible = tableView.indexPathsForVisibleRows?.contains{$0 == indexPath}
            if let v = isVisible, v == true {
                tableView.reloadRows(at: [indexPath], with: .automatic)
            }
    

    检查类似问题:可能会有帮助这一个解决了我的问题。我使用的是核心数据,我向resultfetchcontroller传递了不同的获取请求,并在获取完成后重新加载表。即使获取成功,应用程序也会崩溃。但使用上述方法,重新加载成功。不正确。如果只有一个reloadRowsAtIndexPath,则不需要BeginUpdate/EndUpdate,但如果试图重新加载新添加的行,则不会修复崩溃。查看Nekto的anwer了解详细信息。理论上有道理,但不起作用。我试图重新加载部分,但它仍然崩溃。我使用UITableViewAutomaticDimension的估计页眉和单元格高度作为高度,这是一项要求。@sheetal,如果您采用此答案中的方法,则不必调用reloadRowsAtIndexPaths:withRowAnimation:。基本上是在模型数据结构中添加一行(大多数情况下是数组)。然后调用beginUpdate、insertRowsAtIndexPaths和endUpdates