URLSessionDataTask를 사용하여 API에서 XML 파일을 다운로드하고 있습니다.
XML은 다음과 같습니다 Libxml2를 사용하여 XML을 구문 분석 할 때 RAM을 많이 사용합니다.
<?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은 수천 권의 책을 가질 수있다.
저는 Libxml2의 SAX 파서를 사용하여 XML을 구문 분석합니다. 구문 분석하는 동안 나는 객체
Book
를 작성하고 그래서 같이 XML에서 값을 설정하십시오있는 UITableViewController에서
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
}
을 onBook(book: Book)
대리자 메서드는 배열에 책 객체를 추가하고 jQuery과 업데이트합니다. 여태까지는 그런대로 잘됐다.
이제 문제는 장치의 RAM이 너무 많아서 장치가 느려집니다. XML에 ~ 500 권의 도서가 있으면 500MB 이상의 RAM이 필요합니다. 나는 이유를 모른다. 나는 악기의 RAM을 조회 할 때, 나는 범주 이벤트 역사에서
(100)보다 큰 여러 항목으로_HeapBufferStorage<_StringBufferIVars, UInt16>
에 할당 된 모든 메모리 참조가
을 나열buildBook()
하는 방법입니다
Foundation에서 XMLParser를 사용할 때 onstructor XMLParser(contentsOf: URL)
먼저 전체 XML을 다운로드 한 다음 구문 분석합니다. 정상적인 RAM 사용법을가집니다. 아무리 많은 책이 있더라도. 하지만 UITableView에 최대한 빨리 책을 보여주고 싶습니다. 나는 단지 iOS 용 안드로이드의 XMLPullParser와 같은 것을 원한다.
autoreleasepool {
xmlParseChunk(ctxt, data, Int32(read), 0)
}
당신이 만약이 호출을 변경
는xmlParseChunk(ctxt, data, Int32(read), 0)
상당히 사용되는 메모리의 양을 감소 :
SAX 파서가 XML 데이터를 파싱하는 작은 메모리를 사용한다, 다른 파서를 시도할까요? – aircraft
[XMLTextReader 인터페이스] (http : // xmlsoft.org/xmlreader.html)은 LibXML2에서 "후계자"이기 때문에. 하지만 XML 파일을 다운로드하는 동안 XML 파일을 사용할 수 있는지 알고 있습니까? – ElegyD