Se siete su iPhone, utilizzando l'analisi ad albero può essere uno spreco di memoria proibitivo. Fidati di me, ci sono stato, e ho provato molti approcci diversi negli ultimi cinque mesi di sviluppo della mia applicazione principale per iPhone. L'analisi ad albero funziona bene fino a quando non scarichi il flusso di commenti di qualcuno che contiene 400 commenti molto lunghi, con un clock di circa 600 KB di dati grezzi. A parte le dimensioni dell'albero XML risultante, la memoria allocata internamente durante la creazione di quell'albero può essere enorme.
Finii creando una variante di NSXMLParser che estrae dati da un NSInputStream fornito piuttosto che utilizzare un singolo blocco di dati, e che passa solo 1 KB alla volta nel libxml per la movimentazione (NSXMLParser utilizza libxml troppo, ma passa il 100% dei dati in una volta sola).
Il codice sorgente è disponibile on github (cercare nella cartella StreamingXMLParser). Troverai anche una superclasse delegata; per la maggior parte delle esigenze di analisi è possibile creare sottoclassi AQXMLParserDelegate e implementare -start[Element]WithAttributes: (NSDictionary *) attrs
e -end[Element]
nella sottoclasse. Questi metodi verranno chiamati per te quando vengono scoperti i tag di inizio e fine e all'interno del tag di fine è possibile utilizzare self.characters
per accedere ai caratteri di contenuto o CDATA dell'elemento.
Per ulteriori sulle impronte di memoria relativi dei diversi parser (anche se su Mac, non l'iPhone) Guarda i miei post originale here e il follow-up su NSXMLDocument here.
fonte
2009-05-09 00:44:35
Grazie per informazioni utili. Ho finito con l'adozione di startElement, foundCharacters, endElement pattern e non era male ma si, ora sto notando che initWithContentsOfURL di NSXMLParser sembra scaricare l'intero documento e lasciarlo in memoria anziché farlo streaming, come hai fatto notare. Il che è piuttosto sorprendente poiché non vi è alcun motivo per cui sia necessario accedere all'intero documento quando si utilizza un approccio di analisi basato su eventi. Guarderò StreamingXMLParser. – Marplesoft
Ok ulteriori indagini. Ora sto notando che l'impronta della memoria è peggiorata a causa del download dell'URL rispetto all'effettivo parsing. Sto facendo un download asincrono ma non sembra che stia rilasciando i blocchi di dati già ricevuti. – Marplesoft
Sì, la roba NSURLConnection alloca internamente un bel po 'di memoria mentre fa le cose - e se stai usando SSL ci sono ~ 1MB extra allocati per la pipeline di crittografia. Ho finito per scrivere il mio wrapper su CFHTTPMessageRef e usarlo per ottenere un flusso per alimentare il parser; si trova nello stesso repository github, nella sottocartella HTTPMessage. –