在解析XML时设置ProgressView的进度

时间:2011-03-25 12:01:20

标签: iphone parsing uiprogressview

我正在使用XML文件进行解析。我想显示一个进度条,直到解析过程完成。如何计算ProgressView的进度? 请帮助..

3 个答案:

答案 0 :(得分:6)

首先,计算行数。

NSError *error = nil;
NSString *xmlFileString = [NSString stringWithContentsOfURL:url
                           encoding:NSUTF8StringEncoding error:&error];
_totalLines = [xmlFileString componentsSeparatedByString:@"\n"].count;

然后,捕获委托方法块中的进度。例如:

- (void)parser:(NSXMLParser *)parser 
  didStartElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI 
  qualifiedName:(NSString *)qName 
  attributes:(NSDictionary *)attributeDict
{
    [self.elementStack addObject:elementName];

    NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
    [mainQueue addOperationWithBlock:^{
        _progressView.progress = (CGFloat)[parser lineNumber] / (CGFloat)_totalLines;
    }];
}

示例项目在这里:

https://github.com/weed/p120727_XMLParseProgress

ss

答案 1 :(得分:5)

如果要使用NSXMLParser进行语法分析并知道要解析的文件的长度,则可以通过调用解析器对象上的lineNumber来估计进度,以告诉您解析器在文件中的位置。

progressView.progress = (CGFloat)[parser lineNumber] / (CGFloat)totalLines;

答案 2 :(得分:0)

我正在处理大型文件,需要几秒钟来计算文件中有多少行。

我想出了一个更复杂但更快的解决方案:

  • 使用NSData将文件内容映射到虚拟内存。这是在OS X和iOS上读取大文件的最快方法。如果它是一个中小型文件,它将被加载到RAM中,但大型文件只会部分加载到RAM中。
  • 使用宏中央调度,触发后台任务以10KB块的形式处理数据,计算找到的换行数。
  • 触发另一个大型中央调度任务来解析同一个NSData对象。
  • 每当启动一个新标签时,每隔半秒,检查行计数是否已完成,如果是,则更新进度条。

将文件映射到虚拟内存然后搜索换行字节的速度比我能找到的任何其他方法快10倍,包括一些低级别C选项。在我的SSD配备的Mac上,需要一秒钟来计算一个300万行的文件。

在同一个NSXMLParser对象上与NSData并行的后台线程上执行此操作可确保不会从磁盘读取文件两次(除非文件太大而无法放入RAM中) )。

此处的源代码位于:https://github.com/abhibeckert/Speed-Limit/blob/master/Speed%20Limit/SLOSMImporter.m

注意:我发布的代码适用于iOS 7和OS X 10.9。它仅在OS X 10.9上进行了测试。它可以很容易地修改以适用于旧版本的SDK,只需构建它就可以很容易地修复编译错误。