Uitableview 非预期的表重新加载/刷新(有一定延迟)

Uitableview 非预期的表重新加载/刷新(有一定延迟),uitableview,core-data,swift,ios8,Uitableview,Core Data,Swift,Ios8,Xcode 6-beta 6/7:我创建了一个iOS 8(Swift)博客阅读器应用程序,它有一个概览(表视图)和一个详细视图(web视图)屏幕。如果有互联网连接,应用程序在启动时会从博客加载实际的json数据,并将其作为实体对象保存到核心数据中。首先显示的表视图用核心数据中的对象填充其单元格。包含标题和副标题的单元格按预期加载完毕。一切似乎都很好,但 如果我不进行交互,只是等待,表视图会在大约10秒后快速刷新(单元格变为空白,并在半秒内再次填充相同的文本)。在一切正常后,我可以单击指定的单元格

Xcode 6-beta 6/7:我创建了一个iOS 8(Swift)博客阅读器应用程序,它有一个概览(表视图)和一个详细视图(web视图)屏幕。如果有互联网连接,应用程序在启动时会从博客加载实际的json数据,并将其作为实体对象保存到核心数据中。首先显示的表视图用核心数据中的对象填充其单元格。包含标题和副标题的单元格按预期加载完毕。一切似乎都很好,但

  • 如果我不进行交互,只是等待,表视图会在大约10秒后快速刷新(单元格变为空白,并在半秒内再次填充相同的文本)。在一切正常后,我可以单击指定的单元格并转发到详细视图,我可以返回并选择任何其他单元格

  • 如果我立即开始交互,就像正常情况下一样,我必须单击一个单元格两次,然后才能转发到详图视图。在很短的时间内返回概览时,我发现我的表视图中只填充了我刚才点击的一个单元格,其余的都是空白

    • 我可以再等5-15秒,然后一切自动刷新(从那时起,工作正常),或者
    • 我可以点击那些空白单元格,这些单元格会立即再次可见,然而——当然——我会再次被转发到详细视图或
    • 如果我在细节视图上站的时间更长,比如说读了一些博客,然后再回头,所有的细胞都是可见的,因为有足够的时间来进行这一奇怪的刷新

    • 需要注意的是:如果没有互联网连接,应用程序会成功地从核心数据加载对象,但提到的问题仍然存在。所以,无论如何,我必须等到“第二次刷新”发生后,应用程序才能像我想要的那样运行

    如果这是一个完全未知的问题,您必须查看一些代码以便进一步调查,我很乐意与您分享。但现在我还没有看到一点,因为这或多或少是在使用表视图时实现的基本代码。我对核心数据相当陌生,可能已经监督过一些事情,但到目前为止还没有注意到。 我会非常感谢一些帮助,因为我通常会在询问之前调查很长时间,但这次我真的不知道原因是什么

    编辑:

    可能需要补充的是,我使用Xcode中的“Master Detail Application”模板启动了该应用程序,并介绍了它提供的方法,以使用核心数据中的适当实体对象自动填充单元格(NSFetchedResultsController)。代码的某些部分可能会给出进一步调查的提示(如果需要更多代码,请告诉我):

    编辑2:

    多亏了nzeltzer的输入,我想我已经找到了要点:当代码的某些部分在全局(而不是主)线程上运行时,上面的问题就发生了。所以我做了一些测试:底部的控制台输出显示应用程序第一次构建时的NSThread.isMainThread()结果

    当我第二次运行app a或更多次时,过程如下:核心数据已经有一些值,因此直接配置单元格(Log:
    \是主线程
    )。然后,如果存在internet连接,它将删除(在viewDidLoad中)所有核心数据对象,再次加载json数据,将对象放入核心数据,并再次创建单元格。日志的第二部分现在又不是主线程了。如果我现在在没有internet连接的情况下运行应用程序,第二部分不会被触发,只有第一个带有
    \uuu的单元格配置是主线程

    对这种行为有直接的解释吗

    在任何情况下,分派那些可能导致主线程问题的部件的正确(优雅)方法是什么?它是否与模板的内置NSFetchedResultsController有关,或者某些任务自动分派到全局队列只是正常现象

    日志(应用程序首次构建,10个单元格):


    我也有类似的问题
    您需要在主线程上进行任何ui更改。执行数据请求时,回调可能不在主线程上。因此,要做到这一点,请执行以下操作:

    dispatch_async(dispatch_get_main_queue()){    
        self.tableView.reloadData() // reload table/data or whatever here. However you want.
    }
    

    当您从url加载数据时,将有某种回调,它将被发送到闭包(objc中的一个块)。调用该闭包时,不能保证它位于主线程上。有时可能是,有时不会。为什么要运行
    dispatch\u async
    并告诉它使用
    dispatch\u get\u main\u queue()
    获取主线程呢?您的意思是,在主线程上运行以下代码。所有UI更改都必须从主线程进行

    您也可以像这样重新加载UITableView

    self.tblMainTable.performSelectorOnMainThread(Selector("reloadData"), withObject: nil, waitUntilDone: true)
    

    也许一些代码可以帮助。。。你在CellForRowatineXpath中有什么?@Mike当然,我添加了一些。你是否验证了你的UI更新正在主线程上调度;您的核心数据设置是使用线程限制还是使用适当的替代方案?@nzeltzer我不确定:如果有任何东西被分派到另一个线程,我不会在代码中看到它吗?或者是否有自动在另一个线程上运行的库方法?我还没有听说过更多的核心数据“设置”的细节,但它不是默认的线程限制吗?在大多数情况下,是的。我之所以这么问,是因为这些延迟的UI刷新是从主线程以外的某个线程推送更新的常见症状。我进一步指定了问题(再次选中编辑)。你也在处理这个问题吗?我现在想知道如何用这些新的输入来解决这个问题…所以不做任何事情,表数据就会消失?不,在这些情况下
    dispatch_async(dispatch_get_main_queue()){    
        self.tableView.reloadData() // reload table/data or whatever here. However you want.
    }
    
    self.tblMainTable.performSelectorOnMainThread(Selector("reloadData"), withObject: nil, waitUntilDone: true)