如何在Corona/Lua中高效处理大型tableview

我正在开发一个应用,在其中一个点上,我需要构建一个包含3787个项目的tableView。(顶部有搜索栏,用户不必向下滚动浏览)。然而,将数组插入表格视图需要约5秒钟的时间,导致应用程序启动时或在进入该场景之前出现加载时间。有没有办法缩短这个时间?我考虑过多线程,查找了Lua协同程序,但不完全了解实现异步运行的方法。或者如何在表格加载时显示加载栏。该表格在另一个场景中,因此我使用的是stoyboard.loadScene()。

点赞
用户869951
用户869951

我看到三种选择:

  1. 在应用程序启动时加载表格:这会延迟启动时间,可能会有很大影响(如果本来是1秒,则5秒会明显感受到),并且表格可能永远不会被使用(如果用户不进入那个场景),但此后,表格将立即准备好显示。
  2. 当用户点击某些东西时,再加载表格:应用程序启动快,仅在需要时加载表格,但这会延迟切换到显示表格的场景时间,因此用户可能会认为 GUI 卡住了,因此您需要告诉用户并提供进度指示器。
  3. 在启动时在单独的线程中开始加载表格,最可能需要超过5秒才能到达显示表格的场景,因此应用程序启动速度很快,而且当进入显示表格的场景时,用户会感觉表格加载是瞬间的。但是,有可能用户在完全加载表格之前尝试进入该场景,在这种情况下,您需要提供一些指示,表明 GUI 没卡住,正在进行加载。
  4. 仅加载可见部分的表格。这可能不是一个选项(例如,您需要显示排序后的表格,但数据库不提供具有相同排序的项目,因此您需要加载所有项目)。

我认为你可以处理1、2和很有可能也可以处理#4。对于1和2,您需要提供一些指示,表明加载操作需要一些时间,但除此之外没有太难的东西。对于4,不需要进度,但您需要基于表格的“视图”(可见行的子集)确定要加载的行。

选项在技术上更具挑战性。你是对的,你应该使用协程。它们实际上很容易使用:

  1. 在启动时创建协程:thread = coroutine.create(loadTable)

  2. loadTable 应该被设计为每次只做一小部分工作,并在工作之间进行 yield,例如

    function loadTable()
        ...初始化...
        coroutine.yield()
        while haveMoreRows do
            读取 10coroutine.yield()
        end
        ...清理...
    end
    
  3. 你的代码重复恢复线程,直到线程死亡:coroutine.resume(thread)。在 Corona 的 Runtime 的 enterFrame 处理程序中执行这个操作是一个很好的位置,因为它在每个帧调用。

    function enterFrame(e)
        if thread ~= nil then
             if coroutines.status(thread) == 'dead' then
                 创建表格显示,因此在表格场景中它是即时可用的
                 如果正在显示进度,请隐藏它
                 thread = nil
             else
                 coroutine.resume(thread)
        end
    end
    

在您的场景转换(到显示表格的场景)中,您应检查线程是否不为空,如果不为空,则加载尚未完成,因此您需要在新场景中显示消息,表明表格正在加载;在 enterFrame 中完成加载后,该消息将被删除。

了解协程(协作线程)的一个重要事项是,线程函数可以具有多个 yield 点;在下一次恢复时,函数继续从离开时的地方执行,具有正确的局部状态。

希望你已经看过 http://lua-users.org/wiki/CoroutinesTutorial

2014-01-19 05:34:23