ios - UITableView 崩溃

标签 ios objective-c uitableview

我在 UITableView 中显示一个包含插入、更新和删除的数组对象,偶尔我会收到下面的异常,即使我正在小心地处理更改。我在 GitHub 上有完整的代码示例。

https://github.com/brennanMKE/TableMaddness

此示例项目使用实现 NSCoding 和 NSCopying 以及 isEqual 的对象,以便使用插入、更新和删除更新表可以模拟我在具有相同问题的真实应用程序中所做的事情。我避免使用会使用 NSFetchedResultsController 的核心数据,所以我想知道如果我不使用核心数据,是否应该使用某些东西。

断言失败 -[UITableView _endCellAnimationsWithContext:],/SourceCache/UIKit_Sim/UIKit-2903.23/UITableView.m:1330 2013-11-25 14:43:20.217 TableMaddness[13411:70b] 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无效更新:第 0 节中的行数无效。之后的现有部分中包含的行数更新 (4) 必须等于更新 (4) 之前该部分中包含的行数,加上或减去从该部分插入或删除的行数(1 插入,0 删除)加上或减去行数行移入或移出该部分(0 移入,0 移出)。'

相关代码如下。

    // determine items which need to be inserted, updated or removed
    NSMutableArray *inserts = [@[] mutableCopy];
    NSMutableArray *deletes = [@[] mutableCopy];
    NSMutableArray *reloads = [@[] mutableCopy];

    // look for inserts
    for (NSUInteger row=0; row<fetchedItems.count; row++) {
        SSTItem *item = fetchedItems[row];
        if (![self.currentItems containsObject:item]) {
            // inserts are items which are not already in self.items
            [inserts addObject:[NSIndexPath indexPathForRow:row inSection:0]];
        }
        else {
            NSUInteger otherIndex = [self.currentItems indexOfObject:item];
            SSTItem *otherItem = [self.currentItems objectAtIndex:otherIndex];
            if (![item.modified isEqualToDate:otherItem.modified]) {
                [reloads addObject:[NSIndexPath indexPathForRow:row inSection:0]];
            }
        }
    }

    // look for deletes
    for (NSUInteger row=0; row<self.currentItems.count; row++) {
        SSTItem *item = self.currentItems[row];
        if (![fetchedItems containsObject:item]) {
            [deletes addObject:[NSIndexPath indexPathForRow:row inSection:0]];
        }
    }

    static NSString *lock = @"LOCK";

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (kDelay / 4) * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        // lock is required to prevent inconsistencies when changing view orientation during rotation
        @synchronized(lock) {
            self.currentItems = fetchedItems;

            NSUInteger numberOfRowsInSection = [self tableView:self.tableView numberOfRowsInSection:0];
            DebugLog(@"numberOfRowsInSection: %li", numberOfRowsInSection);
            DebugLog(@"self.items: %li", self.currentItems.count);

            MAAssert(self.currentItems.count == numberOfRowsInSection, @"Match is required");

            if (inserts.count || deletes.count || reloads.count) {
                [self.tableView beginUpdates];
#ifndef NDEBUG
                for (NSIndexPath *indexPath in inserts) {
                    DebugLog(@"Inserting at %li", (long)indexPath.row);
                }
                for (NSIndexPath *indexPath in deletes) {
                    DebugLog(@"Deleting at %li", (long)indexPath.row);
                }
                for (NSIndexPath *indexPath in reloads) {
                    DebugLog(@"Reloading at %li", (long)indexPath.row);
                }
#endif
                [self.tableView insertRowsAtIndexPaths:inserts withRowAnimation:UITableViewRowAnimationAutomatic];
                [self.tableView deleteRowsAtIndexPaths:deletes withRowAnimation:UITableViewRowAnimationAutomatic];
                [self.tableView reloadRowsAtIndexPaths:reloads withRowAnimation:UITableViewRowAnimationAutomatic];
                [self.tableView endUpdates];
            }
        }

        index++;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, kDelay * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
            [self runNextUpdate];
        });
    });

最佳答案

- (void)runNextUpdate {
if (index >= self.dataSets.count) {
    index = 0;

    [self runNextUpdate]; // remove this line
    return;               // or add this line.
}

因为如果这个条件为真,你的代码会几乎同时运行两次,但是数据源还没有更新。

关于ios - UITableView 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20208730/

相关文章:

ios - 在 MKPolyline 上检测触摸手势

iphone - 在 iPhone 上以 IMA4 格式录制单声道

ios - 如何在不依赖通知的情况下获取键盘高度

ios - 为什么有时可以将 NSArray 转换为 NSMutableArray,有时却不能?

ios - UIButton 没有响应在自定义 UITableViewCell 中使用

ios - 使用 UISearchController 和 Objective-C 搜索 UITableView 而不是 UITableViewController

iOS:通过以编程方式添加约束作为唯一指示器获取 View 高度

objective-c - 如何在全屏应用程序中处理 Cocoa 事件

ios - 启用 Show Blended Layers 时 UIButton 部分变红

ios - Xcode 9 Swift 4 UITableView 无法识别的选择器发送到实例