如何在Corona / Lua中有效地处理巨大的桌面视图

时间:2014-01-19 03:38:19

标签: multithreading lua tableview corona large-data

我正在构建一个应用程序,在应用程序的某一点上,我需要构建一个包含3787个项目的tableView。 (顶部有一个搜索栏,因此用户无需一直向下滚动)。但是,将数组插入tableview需要5秒钟,导致应用程序启动时或进入该场景之前的加载时间。有没有办法减少这个时间?我想到了多线程并查找了Lua协程,但是并没有完全理解它们实现异步运行的实现。或者如何在加载表时加载条。该表位于另一个场景中,所以即时使用stoyboard.loadScene()

1 个答案:

答案 0 :(得分:1)

我看到三个选项:

  1. 你在app启动时加载表:这会延迟启动,可能会显着延迟(如果不是1秒则会显着5秒),并且可能永远不需要表(如果用户没有去那个场景)但之后,表格立即可以显示
  2. 你按需加载表(比如当用户点击某些东西时):app启动速度很快,并且只在需要时加载表,但是这会延迟转换到显示表的场景,因此用户可能会认为GUI挂起,所以你需要让用户了解并提供进度指标
  3. 您在启动时开始在一个单独的线程中加载表,并且很可能用户需要超过5秒才能到达显示表的场景,因此应用程序启动将很快并且对用户显示表加载进入显示表格的场景时是瞬间的。但是,用户可能会在表完全加载之前尝试转到该场景,在这种情况下,您需要提供GUI未挂起但正在加载的一些指示。
  4. 您只需加载可见的表格部分。这可能不是一个选项(例如,您需要显示已排序的表,但数据库不提供具有相同排序的项目,因此您需要加载所有项目)。
  5. 我得到的印象是你可以处理1和2,而且很可能也会#4。对于1和2,您需要提供一些指示,表明加载操作需要一些时间,但不会太困难。对于4,不需要进度,但您需要根据表的“视图”(可见行的子集)确定要加载的行。

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

    1. 您在启动时创建协程:thread = coroutine.create(loadTable)
    2. loadTable应设计为一次只进行一小部分工作,并在块之间产生,例如

      function loadTable()
          ...init...
          coroutine.yield()
          while haveMoreRows do
              read 10 rows
              coroutine.yield()
          end
          ...cleanup...
      end
      
    3. 您的代码重复恢复该线程,直到该线程死亡:coroutine.resume(thread)。执行此操作的好地方是在corona的Runtime的enterFrame处理程序中,因为在每个时间帧都会调用它。

      function enterFrame(e)
          if thread ~= nil then 
               if coroutines.status(thread) == 'dead' then
                   create table display so it is instantly available in table scene
                   if showing progress, hide it
                   thread = nil
               else
                   coroutine.resume(thread)
          end
      end
      
    4. 在你的场景转换中(到显示表格的场景),你应该检查线程是否为零,如果是,那么加载还没有完成,所以你显示表正在加载的消息(在新场景中);加载完成后,消息将在enterFrame中删除。

      关于协程(协作线程)的一个重要事项是,线程函数可以有多个屈服点;在下一个恢复中,该函数继续从它停止的位置执行,具有正确的本地状态。

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