UITableView 缺少新可见行 NSInternalInconsistencyException 的单元格

Posted

技术标签:

【中文标题】UITableView 缺少新可见行 NSInternalInconsistencyException 的单元格【英文标题】:UITableView Missing cell for newly visible row NSInternalInconsistencyException 【发布时间】:2017-05-11 04:37:45 【问题描述】:

我的应用遇到了这个问题,不知道出了什么问题。 致命异常:NSInternalInconsistencyException 新可见的第 78 行缺少单元格

这是堆栈跟踪:

Fatal Exception: NSInternalInconsistencyException
0  CoreFoundation                 0x191bbefd8 __exceptionPreprocess
1  libobjc.A.dylib                0x190620538 objc_exception_throw
2  CoreFoundation                 0x191bbeeac +[NSException raise:format:]
3  Foundation                     0x192656710 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]
4  UIKit                          0x198022b3c __46-[UITableView _updateWithItems:updateSupport:]_block_invoke.1049
5  UIKit                          0x197d234b8 +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:]
6  UIKit                          0x197d39bac +[UIView(UIViewAnimationWithBlocks) animateWithDuration:delay:options:animations:completion:]
7  UIKit                          0x197ee8770 -[UITableView _updateWithItems:updateSupport:]
8  UIKit                          0x197eccfbc -[UITableView _endCellAnimationsWithContext:]
9  MyApp                      0x1000ed518 -[UICommentsTableViewController insertNewComment:atLocation:] (UICommentsTableViewController.m:1228)
10 MyApp                      0x1000e99e8 -[UICommentsTableViewController onCommentsReceivedWithMessage:] (UICommentsTableViewController.m:881)
11 MyApp                      0x1000e9094 -[UICommentsTableViewController processWSMessage:] (UICommentsTableViewController.m:803)
12 MyApp                      0x1000e8f84 -[UICommentsTableViewController webSocket:didReceiveMessage:] (UICommentsTableViewController.m:788)
13 MyApp                      0x10009ea30 __30-[SRWebSocket _handleMessage:]_block_invoke (SRWebSocket.m:837)
14 libdispatch.dylib              0x190a769e0 _dispatch_call_block_and_release
15 libdispatch.dylib              0x190a769a0 _dispatch_client_callout
16 libdispatch.dylib              0x190a7b5e8 _dispatch_main_queue_callback_4CF
17 CoreFoundation                 0x191b6d0c0 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
18 CoreFoundation                 0x191b6acdc __CFRunLoopRun
19 CoreFoundation                 0x191a9ad94 CFRunLoopRunSpecific
20 GraphicsServices               0x193504074 GSEventRunModal
21 UIKit                          0x197d53130 UIApplicationMain
22 MyApp                      0x10011ba40 main (main.m:7)
23 libdyld.dylib                  0x190aa959c start

错误发生在这里:

- (void)insertNewComment:(NSIndexSet *)indexSet atLocation:(NSInteger)location

    [self.tableView beginUpdates];

    NSMutableArray *indexArray = [NSMutableArray new];
    if (!indexSet) 
        [indexArray addObject:[NSIndexPath indexPathForRow:location inSection:0]];
     else 
        [indexSet enumerateIndexesUsingBlock:^(NSUInteger index, BOOL *stop ) 
            [indexArray addObject:[NSIndexPath indexPathForRow:index inSection:0]];
        ];
    

    [self.tableView insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationBottom];
    [self.tableView endUpdates];


我正在为单元格使用自动布局,但我手动计算了高度并根据它们的设备方向缓存它们。

身高计算器:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 


    Comment* comment = self.comments[indexPath.row];

    CGFloat cellHeight = [self getHeightForLayoutMode:self.screenMode forCommentID:comment.commentID];

    if(cellHeight > 0) 

        return cellHeight;
    


    if([comment isType2]) 
        [self setHeightForLayoutMode:self.screenMode forCommentID:comment.commentID height:106];
        return 106;
    

    CGFloat width = tableView.bounds.size.width - 100;

    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle defaultParagraphStyle] mutableCopy];
    paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;


    NSDictionary *attributes = @NSFontAttributeName: [UIFont fontWithName:@"MyFont" size:11.0f], NSParagraphStyleAttributeName:paragraphStyle;

    CGRect rect = [comment.message boundingRectWithSize:CGSizeMake(width, CGFLOAT_MAX)
                                                options:NSStringDrawingUsesLineFragmentOrigin
                                             attributes:attributes
                                                context:nil];

    CGFloat height = 31+ceilf(rect.size.height);

    [self setHeightForLayoutMode:self.streamViewController.screenMode forCommentID:comment.commentID height:height];

    return height;

有人遇到了这样的问题 (Crash with Missing cell for newly visible row when updating UITableView),他们刚刚删除了估计的SectionHeaderHeight,但我的代码中没有估计的SectionHeaderHeight。

【问题讨论】:

【参考方案1】:

我找到了问题的原因。

在我的视图控制器中,我有一个文本视图,它将触发键盘显示。我将 UITableView 固定在底部。我将它设置为keyboardWillShow 上的scrollToBottom 并在textview 高度变化时调整插图。一旦键盘显示,tableview 几乎不可见(尤其是在 iPhone 5 上)。

现在的修复是我将 tableview 的底部固定到 textview 的顶部,保持 tableview 的相同高度和可见性,并且我不再需要 scrollToBottom 和调整插图,因为自动布局会处理它。希望它可以帮助某人!

干杯。

【讨论】:

【参考方案2】:

当插入值时节数超出范围时会发生此错误。不是身高问题。

【讨论】:

嗯,这很奇怪,因为我只有 1 个部分。 [indexArray addObject:[NSIndexPath indexPathForRow:location inSection:0]]; 另外,我在崩溃前放了一个日志,这就是我看到的:开始 insertNewComment 位置是:773,评论数是 774,所以 self.cmets.count 是 774,我正在插入在索引 773 处。此外,虽然崩溃发生在所有设备上,但大部分崩溃 (85%) 发生在 iPhone 5、5s、SE 中。

以上是关于UITableView 缺少新可见行 NSInternalInconsistencyException 的单元格的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 中的阴影不一致

使用图像设置 backgroundView 时缺少分组的 UITableView 的单元格分隔符

当单元格不可见时,UITableView indexPathForCell 返回 null

带有 MagicalRecord 庞大数据集的 UItableView

UITableView 禁用用户不可见的行

重新加载 UITableView 数据而不是可见单元格