आप iPhone पर हैं, तो का उपयोग कर पेड़ आधारित पार्स एक निषेधात्मक स्मृति हॉग हो सकता है। मेरा विश्वास करो, मैं वहां गया हूं, और मैंने अपने मुख्य आईफोन एप्लिकेशन के विकास के पिछले पांच महीनों में कई अलग-अलग दृष्टिकोणों की कोशिश की है। वृक्ष-आधारित पार्सिंग तब तक ठीक काम करती है जब तक कि आप 400 की लंबी टिप्पणियों वाली किसी भी टिप्पणी स्ट्रीम को डाउनलोड न करें, कच्चे डेटा के लगभग 600 केबी पर घड़ी करें। परिणामी एक्सएमएल पेड़ के आकार से काफी अलग, उस पेड़ को बनाते समय आंतरिक रूप से आवंटित स्मृति बहुत बड़ी हो सकती है।
मैं जो बजाय डेटा का एक हिस्सा का उपयोग करने से एक की आपूर्ति की NSInputStream से में डेटा खींचती NSXMLParser का एक संस्करण बनाने को बंद कर, और जो से निपटने के लिए libxml में एक समय में केवल 1KB गुजरता (NSXMLParser भी libxml का उपयोग करता है, लेकिन एक बार में 100% डेटा पास करता है)।
स्रोत कोड on github उपलब्ध है (StreamingXMLParser फ़ोल्डर में देखें)। आपको वहां एक प्रतिनिधि सुपरक्लास भी मिलेगा; अधिकांश पार्सिंग जरूरतों के लिए आप AQXMLParserDelegate को उपclass कर सकते हैं और -start[Element]WithAttributes: (NSDictionary *) attrs
और -end[Element]
को अपने उप-वर्ग में कार्यान्वित कर सकते हैं। इन विधियों को आपके लिए बुलाया जाएगा क्योंकि स्टार्ट एंड एंड टैग की खोज की गई है, और अंत टैग के अंदर आप सामग्री वर्णों या तत्व के सीडीएटीए तक पहुंचने के लिए self.characters
का उपयोग कर सकते हैं।
अलग पारसर्स के सापेक्ष स्मृति पैरों के निशान के बारे में अधिक (Mac पर, नहीं iPhone यद्यपि) के लिए अपने मूल ब्लॉग पोस्ट here और NSXMLDocument here पर फॉलोअप देखते हैं।
स्रोत
2009-05-09 00:44:35
धन्यवाद यह उपयोगी जानकारी है। मैंने स्टार्ट एलीमेंट को अपनाने का अंत किया, पाया गया कैरेक्टर, एंडलेमेंट पैटर्न और यह बहुत बुरा नहीं था लेकिन हाँ अब मैं देख रहा हूं कि NSXMLParser initWithContentsOfURL पूरे दस्तावेज़ को डाउनलोड करने लगता है और स्ट्रीमिंग के विपरीत इसे स्मृति में छोड़ देता है - जैसे आपने बताया। जो कि आश्चर्यजनक है क्योंकि जब आप किसी ईवेंट-आधारित पार्सिंग दृष्टिकोण का उपयोग कर रहे हों तो आपको पूरे दस्तावेज़ तक पहुंच की आवश्यकता नहीं है। मैं StreamingXMLParser में देखूंगा। – Marplesoft
ठीक है और अधिक जांच। अब मैं देख रहा हूं कि वास्तविक पार्सिंग की तुलना में यूआरएल डाउनलोड के कारण मेमोरी पदचिह्न मोरेसो है। क्या मैं एसिंक डाउनलोड कर रहा हूं लेकिन ऐसा लगता है कि यह पहले से प्राप्त डेटा भाग जारी नहीं कर रहा है। – Marplesoft
हाँ, एनएसआरएलकनेक्शन सामग्री चीजें करते समय आंतरिक रूप से मेमोरी का एक उचित बिट आवंटित करती है- और यदि आप एसएसएल का उपयोग कर रहे हैं तो एन्क्रिप्शन पाइपलाइन के लिए ~ 1 एमबी अतिरिक्त आवंटित किया गया है। मैंने CFHTTPMessageRef के आस-पास अपना स्वयं का रैपर लिखना और पार्सर को खिलाने के लिए स्ट्रीम प्राप्त करने के लिए इसका उपयोग किया; HTTP मैसेज सबफ़ोल्डर में, एक ही जिथब रिपोजिटरी में है। –