繁体   English   中英

UITableView cellForRowAtIndexPath被提前调用

[英]UITableView cellForRowAtIndexPath gets called to early

我有一个UITableView可以在第一次调用时很好地加载其数组项。 但是,当我刷新tableview时,它会崩溃,因为委托方法cellForRowAtIndexPath被提早调用。 我有一个整数,代表我的主数据数组的索引,并且在刷新按钮中将其重置为0。 但是它崩溃是因为它试图在重置之前重新加载数据。 我通常将indexPath.row用作索引,但是该数组很复杂,并且indexPath.row不会与我要显示的每个单元格匹配。 继承人一些代码,任何帮助表示赞赏。

当我下拉刷新并在viewDidLoad中准备数据时调用此方法

- (IBAction)refresh:(id)sender {
itemIndexer = 0;
[sender beginRefreshing];
[self loadData];
}

我的loadData方法的一部分

-(void) loadData {
dispatch_queue_t backgroundQueue = dispatch_queue_create("com.Foo.myqueue", 0);
dispatch_queue_t mainQueue = dispatch_get_main_queue();

dispatch_async(backgroundQueue, ^{

   [self downloadData];

    dispatch_async(mainQueue, ^{
            [self.tableView reloadData];
            [_rcRefresh endRefreshing];
    });
});

我在viewDidLoad中调用以初始加载tableview:

[self refresh:_rcRefresh];

我正在索引超出数组错误的范围。 我使用断点来确定原因的原因仅仅是因为根本不调用刷新,否则itemIndexer将被设置为0。相反,它比数组大小大1。 如果确实有必要,我可以发布cellForRowAtIndexPath,但是我不确定是否可以在第一次调用时使用它。 因此,总结一下对tableview的第一次调用是可行的,并且数据加载良好,但是刷新使索引超出了数组的范围,就好像从未调用过refresh:一样。

对于您所说的,我只能尝试猜测:

  • 您的numberOfSectionsInTableView / numberOfRowsInSection返回错误的数字。

  • 如果[self downloadData]是异步的(正在发出服务器请求,而不是在等待响应),则在拥有数据后应重新加载Data。

  • 您下载的数据未与您已有的数据正确合并。

当然,更多的代码(numberOfSectionsInTableView,numberOfRowsInSection,cellForRowAtIndexPath,downloadData)肯定会有所帮助。

为了清楚起见,有几点...

  • 如@ k20所示,并不是太早调用tableView:cellForRowAtIndexPath:但是一旦异步过程/方法完成,您就需要更好地管理下载数据。
  • tableView:cellForRowAtIndexPath:UITableView数据源方法,而不是委托方法。 值得一提的是这个脚的细节,因为它可以帮助您或其他人更好地理解您正在编写的代码。 ;)

表视图方法调用就是它们的含义-据我了解,每次UITableViewController initawakeFromNib时,所有表视图方法都按顺序调用。 您必须覆盖的表( tableView:numberOfRowsInSection:tableView:cellForRowAtIndexPath: ,以及您选择覆盖的表仍将以相同的顺序执行。

因此,可能更适合您的问题的标题是:“如何使用异步线程上的下载数据更新UITableView。”

@ k20再次指出正确的解决方案。 您是否尝试放置这两行代码...

        [self.tableView reloadData];
        [_rcRefresh endRefreshing];

在您的异步调用中,而不是返回主队列中?

可能是您编写的代码正在像这样执行...

  1. dispatch_q_t准备局部变量;
  2. 开始下载过程;
  3. 重新加载数据以用于表视图;
  4. 结束刷新[_rcRefresh endRefreshing] ;
  5. 根据所需的时间,然后完成下载过程;

您显然想执行的地方...

  1. dispatch_q_t准备局部变量;
  2. 开始下载过程;
  3. 根据所需的时间,完成下载过程;
  4. 重新加载数据以用于表视图;
  5. 结束刷新[_rcRefresh endRefreshing] ;

尝试我的建议,让我知道你的情况。 希望能有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM