5

我正在使用 NSXmlParser 来解析 rss 提要。到目前为止一切都运行良好。

我预计 rss 提要最终将包含数十/数百个帖子。我目前的解决方案是阅读整个 rss 提要并显示结果。但是,我只想阅读前十篇文章(以防止它解析潜在的数百个项目)。然后在稍后的时间(比如当用户到达表格末尾时)解析接下来的十个帖子。

所以我的问题是我将如何解析前十个帖子,然后解析接下来的十个帖子,然后是接下来的十个帖子,依此类推......

这是我用来获取所有帖子的方法:

- (void)parseXMLFileAtURL:(NSString *)URL
{   
    myArray = [[NSMutableArray alloc] init];

    //convert the path to a proper NSURL or it won't work
    NSURL *xmlURL = [NSURL URLWithString:URL];

    rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
    [rssParser setDelegate:self];
    [rssParser parse];

}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
    //error
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{            

    currentElement = [elementName copy];

    if ([elementName isEqualToString:@"item"]) {
        //clear out our story item caches...
        item = [[NSMutableDictionary alloc] init];

    }

}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{     

    if ([elementName isEqualToString:@"item"]) {
        // save values to an item, then store that item into the array...
    }

}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{

    // save the characters for the current item...

}

- (void)parserDidEndDocument:(NSXMLParser *)parser {

    [myTable reloadData];

}
4

4 回答 4

7

我想以与其他人不同的方式回答,如果您的解析器花了这么长时间来解析 10 和 100 之间的差异是一个重要的人类可测量的量,那么您做错了什么。最好是:

  1. 分析您的解析代码以查找减速(或查找性能更高的 XML 库)
  2. 在后台线程上解析整个批次
  3. 只向用户显示前 10 个,
  4. 在他们去的时候显示记忆中的其余部分。

这是双赢的,因为一次解析所有内容可以使代码更简单,错误更少,并且一次“加载”(显示)一个 RSS“页面”将是闪电般的快速,您的用户会喜欢您(参见 Instagram 示例假装速度)

于 2012-07-08T02:09:40.363 回答
0

绝对在你的类头中创建一个计数变量:

...
@private
  NSUInteger rssCounter;
...
@property (nonatomic, assign) NSUInteger rssCounter;
...

在您的委托初始化方法中:

rssCounter = 0;

然后只要你到达一个元素的末尾就简单地增加这个变量,然后如@Metalmi所述,在开始一个元素时在 if else 块中使用中止解析。

之后,创建一个方法,当您需要再加载 10 个时将变量重置为 0,当您需要再次触发整个过程时可以调用该方法。

就像是:

- (void)restartParsing:(NSString *)url
{
  rssCounter = 0
  [self parseXMLFileAtURL:url];
}

希望这可以帮助。

于 2012-07-07T21:59:45.007 回答
0

您可以调用[rssParser abortParsing]以停止解析。停止后,您需要手动剪切 xml 的第一部分。或者以某种方式告诉网络服务。NSXMLParser 不会让你跳转到那里。

于 2012-07-06T14:37:06.703 回答
0

我同意@coneybeare,这似乎是在后台线程中解析xml并将结果存储在内存中的正确方法。

不过,如果您仍想“逐页”解析 xml,您可以使用xmlParseChunkfrom libxml来完成(例如,请参阅XMLPerformance 示例)。您将需要手动计算项目并将剩余部分存储在某处,但我想这是您可以开箱即用的最接近的功能。

另一种方法是采用任何 Objective-C 免费开源 xml 解析器(甚至可能是 DOM 解析器,例如TBXML)并以适合您的方式打破其内部解析循环。

于 2012-07-08T12:26:14.070 回答