Я загружаю XML-файл из API с помощью URLSessionDataTask.
XML-выглядит следующим образом:Большое использование ОЗУ при анализе XML с использованием Libxml2
<?xml version="1.0" encoding="UTF-8" ?>
<ResultList id="12345678-0" platforms="A;B;C;D;E">
<Book id="1111111111" author="Author A" title="Title A" price="9.95" ... />
<Book id="1111111112" author="Author B" title="Title B" price="2.00" ... />
<Book id="1111111113" author="Author C" title="Title C" price="5.00" ... />
<ResultInfo bookcount="3" />
</ResultList>
Иногда XML может иметь тысячи книг.
Я разбираю XML с помощью анализатора SAX из Libxml2. В процессе анализа я создаю объект Book
и установить значение из XML следующим образом:
private func startElementSAX(_ ctx: UnsafeMutableRawPointer?, name: UnsafePointer<xmlChar>?, prefix: UnsafePointer<xmlChar>?, URI: UnsafePointer<xmlChar>?, nb_namespaces: CInt, namespaces: UnsafeMutablePointer<UnsafePointer<xmlChar>?>?, nb_attributes: CInt, nb_defaulted: CInt, attributes: UnsafeMutablePointer<UnsafePointer<xmlChar>?>?) {
let elementName = String(cString: name!)
switch elementName {
case "Book":
let book = buildBook(nb_attributes: nb_attributes, attributes: attributes)
parser.delegate?.onBook(book: book)
default:
break
}
}
func buildBook(nb_attributes: CInt, attributes: UnsafeMutablePointer<UnsafePointer<xmlChar>?>?) -> Book {
let fields = 5 /* (localname/prefix/URI/value/end) */
let book = Book()
for i in 0..<Int(nb_attributes) {
if let localname = attributes?[i * fields + 0],
//let prefix = attributes?[i * fields + 1],
//let URI = attributes?[i * fields + 2],
let value_start = attributes?[i * fields + 3]//,
/*let value_end = attributes?[i * fields + 4]*/ {
let localnameString = String(cString: localname)
let string_start = String(cString: value_start)
//let string_end = String(cString: value_end)
if let end = string_start.characters.index(of: "\"") {
let value = string_start.substring(to: end)
book.setValue(value, forKey: localnameString)
} else {
book.setValue(string_start, forKey: localnameString)
}
}
}
return book
}
В UITableViewController метод onBook(book: Book)
делегата добавляет объект книги в массив и обновляет UITableView. Все идет нормально.
Проблема теперь в том, что она занимает слишком много ОЗУ устройства, и поэтому мое устройство становится медленным. При ~ 500 книгах в XML требуется 500 МБ ОЗУ. Я не знаю почему. Когда я подстановки ОЗУ в инструментах, я вижу всю выделенную память в категории _HeapBufferStorage<_StringBufferIVars, UInt16>
С множеством записей больше, чем 100 KB
В истории событий метод buildBook()
перечисленных
Когда я использую XmlParser из фонда с с onstructor XMLParser(contentsOf: URL)
, который сначала загружает весь XML, а затем анализирует его, у меня нормальное использование ОЗУ. Неважно, сколько книг. Но я хочу показать книги как можно скорее в UITableView. Я просто хочу что-то вроде XMLPullParser от Android для iOS.
SAX парсер должен использовать небольшую память для анализа данных XML, вы хотите попробовать другой парсер? – aircraft
Я думал о [интерфейсе XMLTextReader] (http: // xmlsoft.org/xmlreader.html) из LibXML2, потому что это «преемник». Но знаете ли вы, могу ли я использовать его во время загрузки XML-файла? – ElegyD