【问题标题】:UITableView insertRowsAtIndexPaths throwing __NSArrayM insertObject:atIndex:'object cannot be nil' errorUITableView insertRowsAtIndexPaths 抛出 __NSArrayM insertObject:atIndex:'object cannot be nil' 错误
【发布时间】:2023-04-05 20:08:01
【问题描述】:

我正在尝试将项目动态插入到我的表格视图中。我的应用程序有一个聊天部分,它在第 0 部分显示旧的(在初始化视图控制器之前从服务器加载)消息,并在第 1 部分显示刚刚发送/接收的消息(最初为零)。加载视图时,所有“旧”消息都已加载并显示,没有问题。当我尝试插入行时,问题就开始了。这是我正在做的事情:

  • 我首先通过添加一个额外项来更新我的表格视图的数据源:[newMessages addObject:newMessage];(newMessage 是我的自定义消息对象的一个​​实例,newMessages 是我的数据源)。我验证我的数据源现在有 1 项(添加前为 0)。
  • 然后我调用以下代码:

    [self.chatTableView beginUpdates];
    [self.chatTableView insertRowsAtIndexPaths:@[[NSIndexPath 
        indexPathForRow:newMessages.count - 1 inSection:1]] 
        withRowAnimation:UITableViewRowAnimationBottom];
    [self.chatTableView endUpdates];
    

我的应用程序在 endUpdates 方法处崩溃,给我这个错误:*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'

我立即检查了newMessage 是否为nil,它不是 nil(并重新检查了我的数据源)所以数据源不是问题。我认为indexPathForRow:newMessages.count - 1 可能是问题所在,并尝试了不同的值(count - 2、count、count + 1),以防万一我遗漏了什么。在这些情况下,我收到另一个错误:'NSInternalInconsistencyException', reason: 'attempt to insert row 1 into section 1, but there are only 1 rows in section 1 after the update'。错误说明了一切,所以问题也不在于indexPathForRow:newMessages.count - 1

我在-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 方法中添加了断点,以查看它何时被准确调用以及返回什么。似乎根本没有调用该方法,断点没有命中(它确实在第一次加载视图并正确加载初始数据时命中,并且我没有在任何地方设置数据源,因此委托/数据源也已连接正确)。我立即检查了其他方法:

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 2;
}

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
    if(section == 0){
        return @"Eski mesajlar";
    }else{
        return @"Yeni mesajlar";
    }
}

这些方法返回正确的值。我在-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 中放置了一个断点,以查看它何时被调用。它显然 [self.chatTableView endUpdates]; 方法内调用的(从线程/队列的调用堆栈中可以看出),但随后 [self.chatTableView endUpdates]; 立即抛出错误,甚至没有进入 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 方法。我见过一些例子(以及其他一些例子),例如:

我已经阅读了那里的答案,但没有一个对我有帮助。我做错了什么?

【问题讨论】:

    标签: ios ios7 uitableview


    【解决方案1】:

    您是否实施了tableView:estimatedHeightForRowAtIndexPath:?我在我自己的一个使用NSFetchedResultsController 的应用程序中注意到了一个类似的问题,当调用tableView:endUpdates 时,应用程序会崩溃并显示相同的错误消息。注释掉 tableView:estimatedHeightForRowAtIndexPath: 为我修复了它。

    【讨论】:

    • 没错。我有那个方法,并评论它解决了这个问题。谢谢,我可能永远也想不通,我会向 Apple 提交错误报告。
    • 我没有使用获取的结果控制器,而是基于网络数据,我可以确认注释掉估计的高度部分也阻止了我的崩溃。
    • 这个答案救了我的命!解决了崩溃并使插入动画更加流畅!谢谢!
    • 当您删除tableView:estimatedHeightForRowAtIndexPath: 方法(或停止使用estimatedRowHeight 属性)时,请确保您完全了解自己在做什么。您现在强制表格视图为表格视图中的 每一 行调用 tableView:heightForRowAtIndexPath:,然后在每次调用 reloadData 或类似内容时显示任何内容 - - 主要的性能影响!因此,删除行高估计的使用并不是一个真正的修复,只是一个似乎是 Apple 错误的解决方法。 (@CanPoyrazoğlu 你有你提交的错误的雷达吗?)
    • 我认为这个“错误”没有完全解决,因为我遇到了相同的崩溃/异常问题并注释掉 tableView:estimatedHeightForRowAtIndexPath: 使它消失(但使 tableView 滚动生涩且无法使用.)
    【解决方案2】:

    关于删除/注释掉 tableView:estimatedHeightForRowAtIndexPath:,这不是我解决它的方法,因为我的委托没有那个方法。

    相反,我实际上在我的viewDidLoad 中设置了tableView.estimatedSectionHeaderHeight = 10.;。通过简单地注释该行,异常不再发生,然后按我的预期工作。

    不过,这太糟糕了,因为我无法说明为什么将其注释掉(或 estimatedHeightForRowAtIndexPath: 方法)会修复它。

    【讨论】:

    • 这对我有帮助,删除了任何 tableView.estimatedSectionHeaderHeighttableView.sectionHeaderHeight 呼叫为我解决了这个问题。这不是他们第一次给我带来麻烦了……我只是从现在开始假装他们不存在,因为他们只会破坏东西……
    • 这也为我解决了这个问题,在 iOS 9.2 上(!)
    • 亲爱的主,这也帮助了我!感谢您现有的@speby!我不得不保留rowHeight = UITableViewAutomaticDimension tho,否则它仍然会失败。
    • 不客气@Gee.E!很高兴我能帮上忙。这是一段时间的实时接收器!
    【解决方案3】:

    我最近解决了这个问题,但没有注释掉 estimatedHeightForRowAtIndexPath:。我遇到的具体问题是我们的表格有许多不同大小的单元格,所以我们只是在估计中使用了平均大小。修复是为了更好地估计插入单元格的大小。

    我的假设是该错误是由表格试图滚动到插入的单元格引起的。显然,当滚动到高度估计过小的插入单元格时,先前估计的 contentSize 会导致问题。

    【讨论】:

      【解决方案4】:

      我遇到了这个问题,并通过在表为空时不插入来解决它。换句话说,如果表没有行,则不要使用insertRowAtIndexPaths。而是将对象添加到您的数组或任何数据源,然后调用[myTableView reloadData]

      【讨论】:

        【解决方案5】:

        我相信您的错误在于 tableView:numberOfRowsInSection: 方法。 insertRowsAtIndexPaths 方法会在调用tableView:cellForRowAtIndexPath 之前调用此方法,并且它与数据源不匹配,可能是问题所在。

        我看到newMessages 是一个局部变量,所以它可能不同步到从tableView:numberOfRowsInSection: 方法返回的数组。

        要解决此问题,只需确保 tableView:numberOfRowsInSection 在更新时返回正确的数字即可。

        另外:即使 newMessages 为 nil,count 方法也会返回 0 - Objective-C 就是这样工作的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-12-05
          • 2022-07-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多