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

时间:2009-07-16 09:41:32

标签: iphone xml parsing asynchronous

我正在构建一个应用程序,它将读取RSS源并将它们呈现在UITableViews中。我搜索谷歌和这里和ai决定使用LibXML。

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

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

我使用LibXML解析我的feed,我这样做:

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事件上的提要的函数。

现在我正在考虑在另一个不在主要线程中的线程中解析它们。有人可以给我一些指示吗?

提前谢谢

3 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:1)

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

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

您可以在操作完成后设置回调,这样您就可以将已解析的数据反馈给您的观看。

答案 2 :(得分:0)

我发布了一个开源RSS/Atom Parser for iPhone,它使得阅读和解析网络订阅源非常容易。

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