Nếu bạn đang sử dụng iPhone, sử dụng phân tích dựa trên cây có thể là bộ nhớ cấm. Tôi tin tưởng, tôi đã ở đó và tôi đã thử nhiều cách tiếp cận khác nhau trong năm tháng phát triển ứng dụng iPhone chính của mình. Phân tích cú pháp dựa trên cây hoạt động tốt cho đến khi bạn tải xuống luồng nhận xét của một người nào đó chứa 400 nhận xét rất dài, tốc độ trong khoảng 600KB dữ liệu thô. Khá xa so với kích thước của cây XML kết quả, bộ nhớ được cấp phát nội bộ trong khi tạo ra cây đó có thể rất lớn.
Tôi vết thương lên tạo ra một biến thể của NSXMLParser mà kéo dữ liệu từ một NSInputStream cung cấp hơn là sử dụng một đoạn duy nhất của dữ liệu, và đó chỉ có 1KB đi tại một thời điểm vào libxml để xử lý (NSXMLParser sử dụng libxml quá, nhưng chuyển 100% dữ liệu trong một lần).
Mã nguồn có sẵn on github (xem trong thư mục StreamingXMLParser). Bạn cũng sẽ tìm thấy một siêu lớp đại biểu trong đó; đối với hầu hết các nhu cầu phân tích cú pháp, bạn có thể phân lớp AQXMLParserDelegate và triển khai -start[Element]WithAttributes: (NSDictionary *) attrs
và -end[Element]
trong lớp con của bạn. Những phương thức này sẽ được gọi cho bạn khi thẻ bắt đầu và thẻ kết thúc được phát hiện và bên trong thẻ kết thúc bạn có thể sử dụng self.characters
để truy cập các ký tự nội dung hoặc CDATA của phần tử.
Để biết thêm về những dấu chân bộ nhớ tương đối của các phân tích cú pháp khác nhau (mặc dù trên Mac, không phải là iPhone) thấy gốc bài viết trên blog của tôi here và followup về NSXMLDocument here.
Nguồn
2009-05-09 00:44:35
Cảm ơn đây là thông tin hữu ích. Tôi đã kết thúc việc sử dụng startElement, foundCharacters, mô hình endElement và nó không quá tệ nhưng bây giờ tôi nhận thấy rằng NSXMLParser initWithContentsOfURL dường như tải toàn bộ tài liệu và để nó trong bộ nhớ trái với luồng nó - như bạn đã chỉ ra. Đó là kinda đáng ngạc nhiên vì không có lý do bạn cần truy cập vào toàn bộ tài liệu khi bạn đang sử dụng một cách tiếp cận phân tích dựa trên sự kiện. Tôi sẽ xem xét trong StreamingXMLParser. – Marplesoft
Ok điều tra thêm. Bây giờ tôi nhận thấy rằng dấu chân bộ nhớ là moreso do tải xuống URL hơn là phân tích cú pháp thực tế. Tôi đang làm một tải xuống async nhưng nó dường như không phát hành các khối dữ liệu đã nhận được. – Marplesoft
Vâng, các công cụ NSURLConnection phân bổ một bit công bằng của bộ nhớ trong khi làm việc của nó - và nếu bạn đang sử dụng SSL có ~ 1MB thêm phân bổ cho các đường ống mã hóa. Tôi vết thương bằng văn bản của riêng tôi wrapper xung quanh CFHTTPMessageRef và sử dụng để có được một dòng để nuôi phân tích cú pháp; đó là trong cùng một kho lưu trữ github, trong thư mục con HTTPMessage. –