更新:
当使用NSXMLParser
类方法initWithContentsOfURL
时,它不是在下载XML提要时进行解析,而是试图将整个XML文件加载到内存中,然后才启动解析过程。如果XML提要很大(使用过量的RAM,固有地低效,因为解析不是与下载并行,而是仅在下载完成后才开始解析,等等),则这是有问题的。
有没有人发现如何在使用NSXMLParser
将提要流式传输到设备时进行解析?是的,您可以使用LibXML2
(如下所述),但似乎应该可以使用NSXMLParser
。但我一直想不起来。
原问题:
我正在努力使用NSXMLParser
从Web流中读取XML。如果您使用initWithContentsOfURL
,虽然接口可能会导致人们推断它将从Web流式传输XML,但它似乎并没有这样做,而是试图在进行任何解析之前首先加载整个XML文件。对于大小适中的XML文件,这很好,但是对于非常大的文件,这就成了问题了。
我已经看到了关于使用NSXMLParser
和initWithStream
的讨论,以及一些定制的NSInputStream
是从web流。例如,有一些答案建议使用following Cocoa Builder post中提到的CFStreamCreateBoundPair
以及Apple Stream Programming Guide 中关于设置套接字流的讨论,但我还没有让它工作。我甚至试着编写我自己的子类NSInputStream
,它使用了NSURLConnection
(它本身就很擅长流媒体),但我无法让它与NSXMLParser
一起工作。
最后,我决定使用LibXML2
而不是NSXMLParser
,正如苹果XMLPerformance示例中所演示的那样,但我想知道是否有人有幸从使用NSXMLParser
的web源中获得流媒体。我已经看到了很多“理论上你可以做 x”的答案,建议从CFStreamCreateBoundPair
到从NSURLRequest
中抓取HTTPBodyStream
,但我还没有遇到一个使用NSXMLParser
流的工作演示。
Ray Wenderlich的文章How To Choose The Best XML Parser for Your iPhone Project似乎证实了NSXMLParser
不太适合大型XML文件,但是所有关于基于NSXMLParser
的可能解决办法的帖子都是关于流处理大型XML文件的,我很惊讶我还没有找到一个可行的演示。有谁知道一个功能NSXMLParser
实现,从web流?显然,我可以坚持使用LibXML2
或其他等效的XML解析器,但是使用NSXMLParser
流的概念似乎非常接近。
2条答案
按热度按时间0kjbasz61#
-[NSXMLParser initWithStream:]
是NSXMLParser
的唯一接口,它当前执行数据的流式解析。将它连接到增量提供数据的异步NSURLConnection
是不方便的,因为NSXMLParser
采用基于阻塞的“拉”方法从NSInputStream
阅读。也就是说,-[NSXMLParser parse]
在处理NSInputStream
时会执行以下操作:为了增量地向这个解析器提供数据,需要一个自定义的
NSInputStream
子类,它将NSURLConnectionDelegate
调用接收到的数据汇集到后台队列或runloop中,然后传递给NSXMLParser
正在等待的-read:maxLength:
调用。概念验证实现如下:
db2dz4w82#
我注意到bdash的答案使用了NSURLConnection。但是根据NSURLConnection Documentation
此API被视为遗留。改为使用NSURLSession。
所以我用NSURLSessionDataTask替换了它。
单元测试代码示例: