heightForRowAtIndexPath中的线程问题

时间:2015-01-22 04:35:25

标签: ios objective-c multithreading uitableview

我在iOS应用中遇到了线程问题。这是一个已经发展了几年的大型应用程序。 (我是这个项目的许多贡献者,并且对它的某些部分只有深刻的理解)。

在某些情况下,应用会进行后台刷新,触发tableview委托方法。偶尔会导致以下异常:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Only run on the main thread!'

我已经深入研究了这个问题并确定在后台刷新期间有些情况下没有从主线程调用tableview委托方法。

所以,我可以在heightForRowAtIndexPath内检查我是否在主线程上。

如果不在主线程上,我可以调用performSelectorOnMainThread来尝试获取单元格高度,唯一的问题是heightForRowAtIndexPath在选择器返回之前返回,因此我的单元格高度将为零。所以,这是鸡蛋之前的鸡肉。情况。如何强制调用heightForRowAtIndexPath中的主线程并确保它在performSelectorOnMainThread完成之前没有返回?或者这甚至可能吗?谢谢!

2 个答案:

答案 0 :(得分:4)

您可以使用GCD实现后台线程,因此您无需手动管理数据.GCD将为您执行所有操作。

  

这是一段代码

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    //// DO some Background Processing Like Data Fetching
    dispatch_async(dispatch_get_main_queue(), ^{
       // Do some UIUpdates in your case call TableView Datasource
        [yourtable reloaddata];
    });
});

夫特:

DispatchQueue.global(qos: .default).async {
        //// Do background tasks Like Data Fetching
        DispatchQueue.main.async {
          // do UI related tasks

        }
    }

答案 1 :(得分:3)

问题不在于heightForRowAtIndexPath,它似​​乎只是在后台线程中重新加载tableview。 尝试这样做

[self.tableview performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];