Question

I'm building an app and at one point in the app I need to construct a tableView that contains 3787 items in it. (There's a search bar at the top so the user doesn't have to scroll all the way down). However it takes a good 5 seconds to insert the array into the tableview, leading to loading time when the app starts up or before going to that scene. Is there a way to trim this time down? I thought of multithreading and looked up Lua coroutines but don't completely understand the implementation to get them running asynchronously. Or how to have a loading bar while the table is loading. The table is in another scene so im using stoyboard.loadScene()

Was it helpful?

Solution

I see three options:

  1. You load the table at app startup: this delays the startup, possibly significantly (5 seconds will be noticeable if otherwise it would be 1 second), and table may never be needed (if user doesn't go to that scene) but after that, the table is instantly ready for display
  2. You load the table on demand (say when user clicks something): app startup fast, and table only loaded if needed, but this delays transition to scene that shows table so user may think GUI hung, so you need to let user know and provide progress indicator
  3. You start loading table at startup in a separate thread, and most likely it will take more than 5 seconds for user to get to scene that shows table so the app startup will be fast AND it will appear to the user that table load is instantaneous when going to scene that shows table. However, there is a chance that user will try to go to that scene before the table has been completely loaded, in which case you need to provide some indication that GUI not hung but load in progress.
  4. You just load the part of table that is visible. This may not be an option (for instance, you need to show table sorted, but database doesn't provide items with same sort so you need to load all items).

I get the impression that you can handle 1 and 2, and most likely #4 too. For 1 and 2 you need to provide some indication that a load operation is taking some time, but otherwise nothing too difficult. For 4 there is no progress needed but you need to determine which rows to load based on the "view" of table (subset of rows visible).

Option is technically more challenging. You are right that you should use coroutines. They are actually quite easy to use:

  1. you create the coroutine at startup: thread = coroutine.create(loadTable)
  2. loadTable should be designed to do only small chunks of work at a time, and yield in between chunks, such as

    function loadTable()
        ...init...
        coroutine.yield()
        while haveMoreRows do
            read 10 rows
            coroutine.yield()
        end
        ...cleanup...
    end
    
  3. your code resumes the thread repeatedly, until the thread dies: coroutine.resume(thread). A good place to do this would be in the enterFrame handler of corona's Runtime since this is called at every time frame.

    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
    

In your scene transition (to the scene that shows the table), you should check if thread is not nil, if so then the load is not yet done so you show the message (in new scene) that table is loading; the message will get removed in the enterFrame as soon as load completed.

An important thing to know about a coroutine (cooperative thread) is that the threaded function can have multiple yield points; at the next resume, the function continues to execute from where it left off, with the correct local state.

Hopefully you have looked at http://lua-users.org/wiki/CoroutinesTutorial.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top