Displaying UIActivityIndicator while performing a SYNCHRONOUS download
I am downloading XML to populate an array used to build UITableView. Until I'm informed otherwise, I believe I have to completely download the array before I can display it in the table (also it's text only and extremely small, so it downloads in a reasonable time on the slowest possible connection). It does take about 3-5 seconds at it's slowest, so it would be nice t开发者_StackOverflowo display the activity indicator in the status bar while it downloads.
I make the call to...
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
...before I do ANYTHING (then turn it off once I've done EVERYTHING), but it just pops and quits in about the minimum amount of milliseconds that make it visible to the human eye.
Any suggestions as to why I'm having this experience?
Thanks, Z@K!
Synchronous downloads are performed on the calling thread and blocks the thread until it is complete, which is probably done on the same thread as your UI. As the download is blocking the thread till its complete you either won't see the activity indicator or it will display and not move till the download is complete.
You will have to put the synchronous download on a separate thread or use NSURLConnection:initWithRequest (which is multithreaded) to be able to have the App respond as expected.
The easy answer for me was GCD, Grand Central Dispatch. I barely had to modify my code at all...
My code started as this...
self.table_array = [self.webQuery downloadAndParseXMLForTable];
[(UITableView *)self.view reloadData];
*webQuery is a custom object that downloads and parses xml data from the web. **downloadAndParseXMLForTable is a custom method that synchronously downloads and parses an XML file, then returns an (NSArray *) object to support a table view.
The modified code below, shows the ONLY changes I had to do to adopt GCD, and keep my UI responsive.
dispatch_queue_t table_download_queue = dispatch_queue_create("com.yourcompany.queuename", NULL);
dispatch_async(table_download_queue, ^{
self.table_array = [self.webQuery downloadAndParseXMLForTable];
dispatch_async(dispatch_get_main_queue(), ^{
[(UITableView *)self.view reloadData];
});
});
dispatch_release(table_download_queue);
That's it! I hope this helps others in my predicament...
Cheers, Z@K!
WARNING: At the WWDC 2010, it was mentioned that GCD cannot currently support SECURE transmissions. I don't remember the details, but the speaker, Quinn, was very adamant about it. I believe the process he suggested required NSOperation...
精彩评论