2012-10-11 41 views
2

我繼承了一些血腥的糟糕的代碼,我試圖去調試。reloadData沒有被立即調用(NSXMLParserDelegate困境)

我使用NSXMLParser解析RSS提要。在解析器:didEndElement:etc:中,當每個新項出現時,我都會調用另一個調用UITableView的reloadData方法的方法。但是,reloadData方法在被調用時不被調用,但後來......在parserDidEndDocument之後:...然後它們都會立即啓動。

好像reloadData請求正在排隊某處,阻塞瞭解析線程。

我該如何強制reloadData在我告訴時觸發,而不是當它想要。我的問題是,因爲它只在所有新聞項目加載後纔會重新加載 - 而且其中有很多 - UI用戶體驗並不理想。

回答

2

您的猜想是正確的。只有當程序控制返回到主運行循環時纔會更新用戶界面。然而,NSXMLParser完全同步工作:parse方法解析整個XML數據(調用委託函數等),並僅在解析完成時才返回。因此在parser:didEndElement:...中調用reloadData沒有立即可見的效果。

如果解析XML數據真的需要這麼多的時間,你不能只是調用reloadDataparse方法又回來了,你必須解析操作移到一個單獨的線程:立即

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
    [myParser parse]; 
}); 

dispatch_async回報,在後臺線程中完成解析。 委託方法因此也在後臺線程上調用。由於更新到UI只能在主線程來完成,你可以繼續在 parser:didEndElement:...如下:

YourType newObject = ... // create new object from XML data 
dispatch_async(dispatch_get_main_queue(), ^{ 
    // assuming that self.dataArray is your data source array for the table view 
    int newRow = [self.dataArray count]; // row number for new object 
    [self.dataArray addObject:newObject]; // add to your data source 
    // insert row in table view: 
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:newRow inSection:0]; 
    [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
          withRowAnimation:UITableViewRowAnimationAutomatic]; 
}); 

使用的insertRowsAtIndexPaths代替reloadData應該給人以動畫「平滑」 UI更新。

我確實希望我的示例代碼中沒有太多的語法錯誤,並且它有幫助。否則,請隨時詢問。

+0

非常感謝*馬丁R!我一定會試試這個。 –