The way to do this is to do your database retrieval asynchronously, in a background queue. This can be tricky to do multi-threaded database operations and one simple solution is to simply create a dedicated serial background queue in which you'll do all of your database interactions (thus the database operations, themselves, are running on a single thread). Thus your background process that loads the data will dispatch database operations to this queue, as will any database interactions you would otherwise do from the main queue.
If you're using FMDB, you can do this with FMDatabaseQueue
, which handles all of this for you. Or you can write your own. (I'd encourage you to check out FMDB, though. If nothing else, look at how it's doing FMDatabaseQueue
and adopt this pattern in your own code.)
If you do this, dispatching the initial load to a background queue that will do all database interactions through this separate dedicated serial database queue, just make sure to dispatch the UI updates of your progress indicator back to the main queue, because all UI interactions should take place on the main queue.
Having said that, there's absolutely no reason why database queries for a user interface should be so slow as to necessitate this, though. I wonder whether it's worth digging into why your database code is so slow, and you may be able to cut the Gordian knot altogether.
A typical example of inefficient database operations is when you store images in the database. Unless you're dealing with very small thumbnail images, SQLite is notoriously inefficient when dealing with BLOB data. The typical solution is to store the images in persistent storage (e.g. your Documents
folder), and only save references to those paths in the database. This offers all sorts of potential optimizations.
In your comment, you mention that the database maintains URLs of images. Well, in that case, you can refrain from retrieving the images in your loadData
routine, and instead employ "lazy loading" of the images, namely load the images in a just-in-time manner, only as they're needed. You can achieve this using a UIImageView
category that does asynchronous loading, such as SDWebImage
or, if you're already using AFNetworking
, you can use its UIImageView
category. If you google "lazy loading UIImage", you'll probably find tons of wonderful links, tutorials, etc. But both of these categories provide not only a easy "lazy loading" mechanism, but also provide caching of images, etc.
But the ideal scenario, rather than designing a progress view for a slow loading process, just refactor your design, completely eliminating this performance bottleneck. It would be a shame to go through the work of designing a progress view for an inefficient loading interface.