加载和解析xml文档在iphone中冻结我的GUI

问题描述:

我正在构建一个应用程序,它将读取rss提要并将它们呈现在UITableViews中。我搜索了谷歌,这里和ai决定使用LibXML。加载和解析xml文档在iphone中冻结我的GUI

当我的应用程序启动时,检查它是否有有效的互联网连接,并抓取一个rss提要,我从中提取一些数据,然后用tableViews制作一个uiTabBar。解析第一个rss提要并构建UITabBar后,对于我的uiTabBar中的每个按钮,我都有一个不同的rss提要(类别)。当我有一个很好的互联网连接(wifi),甚至3G我的应用程序工作真的很好,但当互联网连接遭受我的应用程序也是如此。

因为我一个接一个地解析所有的feed,并且在主线程中GUI只是停止响应,这是一个问题。

我使用的libxml解析我的饲料,我不喜欢这样写道:

CXMLDocument *rssParser = [[[CXMLDocument alloc] initWithContentsOfURL:url options:0 error:nil] autorelease]; 

NSArray *resultDate = NULL; 
resultDate = [rssParser nodesForXPath:@"//channel" error:nil]; 

for(CXMLElement *date in resultDate) 
{ 
    NSString *data = (NSString *)[[date childAtIndex:12] stringValue]; 
    [self setLastBuildDate:[[self parseDate:data] copy]]; 
    break; 
} 

NSArray *resultNodes = NULL; 
resultNodes = [rssParser nodesForXPath:@"//item" error:nil]; 

for(CXMLElement *resultElement in resultNodes) 
{ 
    NSMutableDictionary *feed = [[NSMutableDictionary alloc] init]; 
    int counter; 

    for(counter = 0; counter < [resultElement childCount]; counter++) 
    { 
     [feed setObject:[[resultElement childAtIndex:counter] stringValue] forKey:[[resultElement childAtIndex:counter] name]]; 
    } 
    [links addObject:[feed objectForKey:@"link"]]; 
    [feedsList addObject:[feed copy]]; 
    [feed release]; 
} 
[newsTable reloadData]; 

我想,当我把在uitabbar按钮来解析为第一个按钮饲料和其他的人,但我不能调用捕获和解析-didselectitem事件上的feed的函数。

现在我想解析他们在另一个线程不在主要..有人可以给我一些指针?

谢谢你提前

看看NSOperation和NSOperationQueue。它们对于多线程非常有用。

基本上是NSOperation的子类,并将你的代码写入主要方法。然后将您的操作添加到操作队列中,并且每个操作都将在另一个线程上运行。

您可以在操作完成时设置回调,以便将解析的数据反馈回您的视图。

+0

它的工作原理,谢谢。 – 2009-07-16 13:30:53

基本问题是initWithContentsOfURL:阻塞,直到它从网上获取数据,这可能需要几秒钟。如果您在应用程序的主线程中调用它,则基本上会在网络流量期间锁定整个应用程序。

另一种选择是使用NSURLConnection来下拉数据。它不如initWithContentsOfURL:的单一方法调用方便,但是本质上是异步的。因此,您不必自行实现线程和回调,而只需实现几个委托方法,然后创建NSURLConnection的实例。

有关更多信息,请参阅URL loading system的官方文档。

我已经发布了一个开源的RSS/Atom Parser for iPhone,它使得阅读和解析web feed非常容易。

您可以将其设置为异步下载数据,也可以同步在后台线程中运行它以收集馈送数据。这样,当数据被解析时,你的UI将是免费的。