2012-05-13 11 views
9

में कब लपेटना चाहिए, मैं उद्देश्य-सी के लिए एक नया हूं, और मुझे बुनियादी स्मृति प्रबंधन नियम जैसे retainreleaseautorelease पर पता है। लेकिन मुझे नहीं पता कि मैं अपना कोड ऑटोरेलीज पूल में कब लपेटूं और क्यों?मुझे अपना कोड ऑटोरेलीज पूल

उत्तर

21

अन्य प्रदर्शन अनुकूलन के साथ, आपको आम तौर पर केवल अतिरिक्त ऑटोरेलीज पूल जोड़ना चाहिए यदि आपको उच्च स्मृति उपयोग और प्रोफाइलिंग (उदाहरण के लिए, उपकरण का उपयोग करके) समाधान के रूप में आपको अतिरिक्त ऑटोरेलीज पूल की ओर ले जाता है।

उसने कहा, आप कोड को लपेट सकते हैं जो एक ऑटोरेलीज पूल में एक तंग पाश में बड़ी संख्या में अस्थायी वस्तुओं को बनाता है। एक डिफ़ॉल्ट लूप चक्र के अंत में डिफ़ॉल्ट ऑटोरेलीज पूल निकाला जाता है। इसलिए, यदि आप अपने कोड में लूप के प्रत्येक पुनरावृत्ति में बहुत से अस्थायी ऑब्जेक्ट्स बना रहे हैं, तो आपके पूरे लूप के चलने तक डिफ़ॉल्ट ऑटोरेलीज पूल नहीं निकाला जाएगा, जिसका अर्थ है कि आपके द्वारा बनाई गई सभी अस्थायी वस्तुओं को जोड़ दिया जा सकता है एक उच्च अस्थायी स्मृति उपयोग (कभी-कभी "उच्च जल चिह्न" कहा जाता है)। आप लूप के प्रत्येक पुनरावृत्ति को @autoreleasepool में लपेट सकते हैं ताकि उस लूप पुनरावृत्ति में जल्द ही रिलीज़ होने वाली अनियंत्रित, स्वत: समाप्त, अस्थायी वस्तुओं का कारण बन सके।

+0

आपने मुझे बचाया। मेरे पास कई लूपों में बहुत सी संख्याएं बनाने के लिए एक लंबी चल रही गणना विधि है। उपकरणों में स्मृति उपयोग बढ़ने के बाद भारी मात्रा में गिर रहा है और गिर रहा है। एकल लूप लपेटने के लिए '@ autorelease' का उपयोग कर कोई कमी है? यह वास्तव में ऐप्पल द्वारा अनुशंसित नहीं है, है ना? – JFS

+2

ऐप्पल द्वारा उन मामलों में अनुशंसा की जाती है जहां यह उचित है। यहां प्रलेखन देखें: https://developer.apple.com/library/ios/DOCUMENTATION/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html –

+0

एंड्रयू, आप बस कमाल हैं! जब तक मुझे यह सुझाव नहीं मिला तब तक मुझे उस स्मृति समस्या के कारण सिरदर्द था। यह आसान है और बस कमाल काम करता है। मैं अब अपने ऐप में और अधिक गणना की अनुमति भी दे सकता हूं। धन्यवाद! – JFS

1

सभी ऑटोरेलेज्ड ऑब्जेक्ट तकनीकी रूप से एक ऑटोरेलीज पूल के अंदर रखे जाते हैं। आमतौर पर आपके मुख्य फ़ंक्शन के अंदर बनाया गया डिफ़ॉल्ट होता है। एक गैर-डिफ़ॉल्ट autorelease पूल के भीतर वस्तुओं को लपेटने के लिए, आमतौर पर एक अनुकूलन के रूप में किया जाता है।

आमतौर पर एक स्पष्ट ऑटोरेलीज पूल का उपयोग करने की आवश्यकता नहीं होती है क्योंकि डिफ़ॉल्ट ऑटोरेलीज पूल स्वचालित रूप से आपके ऐप के रन लूप के भीतर निकाला जाता है। हालांकि, अगर आपके पास ऐसा ऐप है जो आपके ईवेंट हैंडलर से लौटने से पहले कई ऑटोरेलेज्ड ऑब्जेक्ट्स बनाता है, तो यह उन ऑब्जेक्ट्स के लिए बहुत सारी मेमोरी का उपयोग कर सकता है। तो यदि आप अपने कोड को एक स्पष्ट ऑटोरेलीज पूल के अंदर लपेटते हैं, तो ऑटोरेलेज्ड ऑब्जेक्ट्स को डिफ़ॉल्ट पूल के बजाय वहां रखा जाएगा। यह आपको ऑटोरेलेज्ड ऑब्जेक्ट्स को जमा करने से रोकने के लिए समय-समय पर इस पूल को खाली करने की अनुमति देता है।

12

करने के लिए पिछले जवाब लागू होता है:

एक स्वत: रिहाई पूल से जोड़ रहे है वस्तुओं के लिए स्वचालित रूप से एक release संदेश भेजने के लिए प्रयोग किया जाता है।

आईओएस या कोको प्रोग्राम में, एक ऑटो-रिलीज पूल स्वचालित रूप से मुख्य धागे पर बनाया जाता है, और इसे रन लूप के अंत में निकाला जाता है।

उस ने कहा, एक अन्य थ्रेड पर ऑटो-रिलीज ऑब्जेक्ट्स का उपयोग करते समय एक ऑटो-रिलीज पूल अनिवार्य है।

तो यदि आप किसी विधि को थ्रेड को अलग करते हैं, तो अपने थ्रेडेड कोड को ऑटो-रिलीज़ पूल के अंदर लपेटें। अन्यथा, थ्रेड में बनाए गए ऑटो-रिलीज़ ऑब्जेक्ट्स केवल रिसाव होंगे।

एक ऑटो-रिलीज पूल का एक अन्य उपयोग कोड के कुछ हिस्सों का अनुकूलन है जो बहुत मेमोरी का उपयोग करेगा, इसलिए वे रन लूप के अंत से पहले मुक्त हो जाते हैं।

लेकिन यह केवल ऑटो-रिलीज ऑब्जेक्ट्स से संबंधित है।

उदाहरण के लिए:

- (void)test 
{ 
    NSMutableArray * a = [ [ NSMutableArray alloc ] init ]; 

    [ a release ]; 
} 

एक स्वत: रिहाई पूल यहां कोई आवश्यकता नहीं है, तो आप एक स्वत: जारी की वस्तु नहीं है के रूप में।
a वैरिएबल तुरंत मुक्त कर दिया जाएगा, क्योंकि इसे स्पष्ट रूप से आवंटित किया गया था, और जारी किया गया था।

अब इस:

- (void)test 
{ 
    NSMutableArray * a = [ NSMutableArray arrayWithCapacity ]; 
} 

यहाँ आप एक सुविधा निर्माता का उपयोग कर रहे हैं, जिसका अर्थ है आप उस वस्तु पर स्वामित्व नहीं है।
इसका यह भी अर्थ है कि ऑब्जेक्ट को वर्तमान ऑटो-रिलीज़ पूल में जोड़ा गया था (यदि कोई है तो)।

तो जब यह स्वत: रिहाई पूल बहा दिया जाता है यह मुक्त हो जाएगा, तो यह कुछ चक्र ले सकता है ...

कोड आप लिख रहे हैं के भाग स्मृति का एक बहुत का उपयोग करता है, तो आप एक और उपयोग कर सकते हैं autorelease पूल, तो अपने ऑटो जारी की वस्तुओं मुक्त कर दिया जाता है जब आपके विधि रिटर्न:

- (void)test 
{ 
    @autoreleasepool 
    { 
     NSMutableArray * a = [ NSMutableArray arrayWithCapacity ]; 
    } 
} 
0

वहाँ है, तथापि, तीन बार आप अपने खुद के autorelease पूल ब्लॉकों का उपयोग कर सकते है जब इस प्रकार हैं:

  1. यदि आप ऐसे प्रोग्राम लिख रहे हैं जो यूआई फ्रेमवर्क पर आधारित नहीं है, जैसे कमांड लाइन टूल।

  2. यदि आप एक लूप लिखते हैं जो कई अस्थायी वस्तुओं को बनाता है। आप अगली पुनरावृत्ति से पहले उन ऑब्जेक्ट्स का निपटान करने के लिए लूप के अंदर एक ऑटोरेलीज पूल ब्लॉक का उपयोग कर सकते हैं। लूप में एक ऑटोरेलीज पूल ब्लॉक का उपयोग करने से एप्लिकेशन की अधिकतम मेमोरी पदचिह्न को कम करने में मदद मिलती है।

  3. यदि आप द्वितीयक धागे को जन्म देते हैं।

संबंधित मुद्दे