I have inherited some bloody awful code that I am trying to debug.
I’m parsing an RSS feed, using NSXMLParser. In parser:didEndElement:etc:, as each new item appears, I fire another method that invoke’s a UITableView’s reloadData method. However, the reloadData methods are not called when they are invoked, but later … after parserDidEndDocument: … then they all fire at once.
It seems like the reloadData requests are queuing up somewhere, blocking on the parsing thread.
How can I force reloadData to fire when I tell it, not when it wants to. My problem is that since it only reloads after all the news items have loaded — and there are a lot of them — the UI experience is suboptimal.
Your conjecture is correct. Updates to the user interface are only done when program control returns to the main run loop.
NSXMLParserhowever works completely synchronously: Theparsemethod parses the entire XML data (calling the delegate functions etc) and returns only when parsing is done. CallingreloadDatainparser:didEndElement:...has therefore no immediately visible effect.If parsing your XML data really takes so much time that you cannot just call
reloadDatawhen theparsemethod has returned, you have to move the parsing operation to a separate thread:dispatch_asyncreturns immediately and the parsing in done on a background thread.The delegate methods are therefore also called on the background thread. Since updates to the UI must only be done on the main thread, you could proceed as follows in
parser:didEndElement:...:Using
insertRowsAtIndexPathsinstead ofreloadDatashould give a “smoother” UI update with animation.I do hope that there are not too many syntax errors in my sample code and that it helps. Otherwise feel free to ask.