【问题标题】:UITableView's reloadData sometimes does not call numberOfRowsInSectionUITableView 的 reloadData 有时不调用 numberOfRowsInSection
【发布时间】:2013-05-19 11:47:20
【问题描述】:

[tableView reloadData] 不调用numberOfRowsInSection:(NSInteger)section

如果我看到这样的问题,我会在stackoverflow中写什么作为答案:

  • 确保委托和数据源已完美连接。
  • 以防万一检查您是否从主线程调用它。

我在提问之前尝试了我的答案。

我在 MyTableView 类(从 UITableView 扩展)中放入以下行

- (void)reloadData{
    NSLog(@"MyTableView (reloadData) self.dataSource: %@, delegate: %@, isMainThread: %d",self.dataSource,self.delegate,[NSThread isMainThread]);

    [super reloadData];

    [self.delegate performSelector:@selector(tableReloaded:) withObject:self];
}

我看到它是从主线程和数据源调用的,并且委托永远不会为零。

我并不好奇为什么 tableView 不调用 cellForRow,因为它首先必须调用 numberOfRows 来查看结果是否 > 0。但是,它也不会调用 numberOfRows...

有什么想法吗? tableView 放弃调用 numberOfRows 函数的原因是什么?

更新: 我已经在 reloadData 函数中添加了新行来打印 FullStack 以查看它是否是从 tableView 自己的函数中调用的。结果:它们在 tableView 之外被调用,因此不应该有任何意外行为。

更新 2: “有时”:在我的用户开始说“有时”他们看不到表格中的更改后,我发现了这个问题。之后,我尝试在 XCode 中连续点击运行按钮,直到应用程序打开时出现此错误。 (我运行的 30% 的百分比显示此错误)。当它发生时,在我重新启动应用程序之前,reloadData 永远不会再次工作。

更新3: 我输入了self.dataSource==myExpectedViewController[self.dataSource tableView:self numberOfRowsInSection:0] 来查看代表是否不为零,也许他们正在被克隆等。结果为True,并且numberOfRows 正确返回> 0。所以代表是正确的,我有比零更多的项目。

更新4: 我尝试使用新的 UITableView(删除我的自定义 UITableView),得到了相同的结果。

更新5: 我在屏幕上放置了一个按钮,用于重新创建表格并设置其代表。每当问题中的问题发生时,我点击这个按钮,一切都开始完美运行。所以,一定有什么东西会破坏 UITableView 的内部结构,这会使对 reloadData 的每次调用都无效,但我仍然找不到它。

【问题讨论】:

  • 如果numberOfSectionsInTableView: 调用返回零,您将不会收到numberOfRowsInSection: 调用。
  • 你能确认 numberOfSectionsInTableView: 被调用并且返回 > 0 吗?
  • 我还没有实现 numberOfSectionsInTableView (应该返回 1),但现在我实现了它并手动返回 1 并放置一个 NSLog 以查看它是否到达那里。不幸的是,它也没有到达那里。
  • 您是否设置了表格视图的数据源并委托给此类?
  • 在问题标题中,它说“有时”。 “有时”是什么意思?

标签: ios uitableview


【解决方案1】:

已编辑:我尝试复制问题并发现,当我在当前视图控制器上呈现另一个视图控制器时,它具有此表视图。然后 1. 尝试用一些数据重新加载这个 tableview 和 2. 同时解除了我的 currentviewcontroller 顶部的 viewcontroller 动画,然后因为在这个持续时间内,table view 不可见,所以它不会被重新加载。

要解决此问题,您可以在此处设置延迟或使用该动画的完成块来重新加载表格并生效。

否则问题可能与线程有关,UIElement 应仅在主线程上更新。

在API调用和其他过程中,我们进入了其他线程,并且在更新UIElement之前我们大多忽略了检查我们是否在主线程。

您应该使用 DispatchQueue.main.async{yourTable.reloadData()} 在主线程中调用 yourTable.reloadData() 并确保在主线程中调用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 2010-12-17
    • 2023-03-30
    相关资源
    最近更新 更多