views:

66

answers:

5

My app has a navigation controller which push and pop a series of views. One of the tableViews loads .xml file from URL and it takes 4-5 seconds. If I click the back button on the navigation bar, it will only respond after the content of the table finish loading. Is there an easy way to load the content asynchronously so that the app will still respond to my gesture on the navigation bar? p.s. I search this on the Internet and people are talking about multithreading. I don't know a lot about threads so please be more specific. Thanks in advanced =)

A: 

You will likely need to implement a multithreaded solution. The topic of multithreaded applications is huge and a detailed answer as such would result in a book, the likes of which is probably better described elsewhere anyhow.

The basics will involve one or more "worker" threads that fetch the XML files and report back to the main thread when the information is available. Implementing this for the iPhone/iPad shouldn't be too difficult, as the OS provides many threading primitives that make this job much easier for the developer.

fbrereto
+1  A: 

You should asynchronously reload remote data. Here you find additional information on how to load data with NSURLRequest with a delegate object. In this case your application will not stuck until the file is loaded completely (or a timeout/error happens).

unset
thx! i think i make it work now using the code you provided.
Brian
A: 

You should look at NSURLConnection

Be sure to implement:

- (void)connectionDidFinishLoading: (NSURLConnection*)connection
MrAleGuy
+1  A: 

Apple's XMLPerformance sample application is written specifically to demonstrate how to parse XML via the libxml2 SAX parser (via stream). Using a stream parser is useful for fast, asynchronous updates, as well as for keeping your app's memory profile low.

If you put XML data into a Core Data store, and hook up your table view to an NSFetchedResultsController and its delegate methods, you can get your table to update itself continuously with very little code. Core Data and the fetched results controller are well beyond the scope of this answer, but you can search Stack Overflow and Google for more information about these topics.

To keep things simple you can just put your data into an NSMutableArray and reload the table view, or specific sections and rows, when the array state changes, but you would have to manage table view updates yourself.

Note that, beyond the data model, handling the view can get complicated quickly; clicking on the back button will cause the view controller to be released, as well as any associated properties, so you need to be careful to manage canceling parsing of XML from your view controller and also manage any allocated memory for your data model that resides in the view controller. Otherwise, you'll run into memory leaks or exceptions from accessing released objects once the view controller is fully released.

To make this easier on yourself, you'll want to read up on NSOperation, NSOperationQueue and KVO, which will help you track the state of operations and do clean-up before the view controller is popped. The NSOperation class makes it easy to run jobs in the background. There are other, manual ways to do threading and locking, but they are not nearly as pleasant and clean as NSOperation.

Reading Apple's NSOperation documentation will help you immensely, as well as doing smaller test applications to get your feet wet with the various frameworks and classes involved with taking your app to the next level of complexity.

Alex Reynolds
+1  A: 

Take a look at Apple's LazyTableImages example code. It does exactly this using threads. Also look at the answers to this SO question.

This other SO answer provides code for a remoteImage class, which I've used for this and it works well.

progrmr