Si estás en el iPhone, usando análisis basado en árboles puede ser un cerdo de la memoria prohibitivo. Confíe en mí, he estado allí, y he intentado muchos enfoques diferentes en los últimos cinco meses de desarrollo de mi aplicación principal de iPhone. El análisis basado en árboles funciona bien hasta que descarga la secuencia de comentarios de alguien que contiene 400 comentarios muy largos, registrando aproximadamente 600 KB de datos sin formato. Aparte del tamaño del árbol XML resultante, la memoria asignada internamente al crear ese árbol puede ser enorme.
I terminaron crear una variante de NSXMLParser que tira de datos desde un NSInputStream suministrado en lugar de utilizar un único fragmento de datos, y que pasa solamente de 1 KB a la vez en libxml para el manejo (NSXMLParser utiliza libxml también, pero pasa el 100% de los datos de una vez).
El código fuente está disponible on github (buscar en la carpeta StreamingXMLParser). También encontrarás una superclase de delegado allí; para la mayoría de las necesidades de análisis, puede subclase AQXMLParserDelegate e implementar -start[Element]WithAttributes: (NSDictionary *) attrs
y -end[Element]
en su subclase. Se buscarán estos métodos cuando se descubran las etiquetas de inicio y fin, y dentro de la etiqueta del final puede usar self.characters
para acceder a los caracteres de contenido o CDATA del elemento.
Para más información sobre las huellas de memoria relativas de los diferentes programas de análisis (aunque en el Mac, no el iPhone) ver mi post original del blog here y el seguimiento de NSXMLDocument here.
Gracias esta es información útil. Terminé adoptando el patrón startElement, foundCharacters, endElement y no fue tan malo, pero sí ahora me doy cuenta de que NSXMLParser initWithContentsOfURL parece descargar todo el documento y dejarlo en la memoria en lugar de transmitirlo, como usted señaló. Lo cual es algo sorprendente ya que no hay ninguna razón por la que necesite acceder al documento completo cuando usa un enfoque de análisis basado en eventos. Veré en StreamingXMLParser. – Marplesoft
Ok más investigación. Ahora me doy cuenta de que la huella de memoria es más debido a la descarga de URL que el análisis real. ¿Estoy haciendo una descarga asíncrona pero parece que no está liberando los fragmentos de datos ya recibidos? – Marplesoft
Sí, el material NSURLConnection asigna un poco de memoria internamente mientras está haciendo cosas, y si está utilizando SSL hay ~ 1MB extra asignado para la canalización de encriptación. Terminé escribiendo mi propio envoltorio alrededor de CFHTTPMessageRef y usándolo para obtener un flujo para alimentar el analizador; eso está en el mismo repositorio github, en la subcarpeta HTTPMessage. –