16

मैं मेमोरी प्रबंधन के बारे में सेब से प्रलेखन पढ़ रहा था जब मुझे ऑटोरेलीज पूल ब्लॉक मिला और कुछ मुझे सोचने लगा।आईओएस ऑटोरेलीज पूल ब्लॉक

Any object sent an autorelease message inside the autorelease pool block is 
released at the end of the block. 

मुझे यकीन नहीं है कि मैं इसे पूरी तरह से समझता हूं। एक ऑटोरेलीज पूल ब्लॉक के अंदर बनाई गई कोई भी वस्तु ब्लॉक के अंत में रिलीज हो जाती है क्योंकि यह जीवन काल है। ऑब्जेक्ट पर ऑटोरिलीज को कॉल करने की आवश्यकता क्यों होगी जब यह ब्लॉक के अंत तक पहुंचने पर वैसे भी रिलीज होने जा रहा है?

साफ होने के लिए, मैं एक उदाहरण देना होगा, मैं क्या सोच रहा हूँ की:

@autoreleasepool { 

    MyObject *obj = [[MyObject alloc] init]; // no autorelease call here 

    /* use the object*/ 
    //.... 
    // in the end it should get deallocated because it's lifespan ends, right? 
    // so why do we need to call autorelease then?! 
    } 

पुनश्च: कृपया मुझे बताओ नहीं है कि एआरसी की वजह से हम कुछ काम करने की जरूरत नहीं है क्योंकि एआरसी उनका ख्याल रखता है। मैं इसके बारे में पूरी तरह से अवगत हूं, लेकिन मैं स्मृति प्रबंधन के तंत्र को समझने के लिए कुछ ही क्षणों के लिए एआरसी को छोड़ना चाहता हूं।

उत्तर

27

Autorelease बस उस ऑब्जेक्ट से एक गिनती गिनती को हटा देता है जो तुरंत सी में स्मृति को "मुक्त" नहीं करता है। जब ऑटोरेलीज पूल 0 की गिनती के साथ सभी ऑटो रिलीज ऑब्जेक्ट्स को समाप्त करता है तो उनकी याददाश्त समाप्त हो जाएगी।

कभी-कभी आप बहुत सारी वस्तुएं बनाते हैं। एक उदाहरण एक लूप होगा जो हर बार जब यह पुनरावृत्त होता है और स्ट्रिंग में नया डेटा जोड़ता है तो नए तार बना रहा है। आपको स्ट्रिंग के पिछले संस्करणों की आवश्यकता नहीं हो सकती है और उन लोगों द्वारा उपयोग की जाने वाली मेमोरी को खाली करना चाहेंगे। आप स्वाभाविक रूप से इसे करने के लिए इंतजार करने के बजाए ऑटोरेलीज पूल का स्पष्ट रूप से उपयोग करके इसे पूरा कर सकते हैं।

//Note: answers are psudocode 

//Non Arc Env 
@autoreleasepool 
{ 

    MyObject *obj = [[MyObject alloc] init]; // no autorelease call here 
    //Since MyObject is never released its a leak even when the pool exits 

} 
//Non Arc Env 
@autoreleasepool 
{ 

    MyObject *obj = [[[MyObject alloc] init] autorelease]; 
    //Memory is freed once the block ends 

} 
// Arc Env 
@autoreleasepool 
{ 

    MyObject *obj = [[MyObject alloc] init]; 
    //No need to do anything once the obj variable is out of scope there are no strong pointers so the memory will free 

} 

// Arc Env 
MyObject *obj //strong pointer from elsewhere in scope 
@autoreleasepool 
{ 

    obj = [[MyObject alloc] init]; 
    //Not freed still has a strong pointer 

} 
+0

तो यह मेरे प्रश्न का उत्तर कैसे दे रहा है? मैंने केवल इस तरह के उत्तरों से बचने के लिए एक सरल उदाहरण प्रदान किया है जिसमें प्रश्न के साथ बहुत कुछ नहीं है।मैंने छोटे उदाहरण में टिप्पणियां भी शामिल कीं। – Teo

+1

आमतौर पर आप केवल उस फ़ंक्शन में ऑटोरेलीज पूल का उपयोग करते हैं जहां उच्च स्मृति उपयोग होता है और आपको इसे सामान्य रूप से सामान्य रूप से मुक्त करने की आवश्यकता होती है। अनुच्छेद का उद्देश्य संदर्भ जोड़ने का इरादा था। – Kibitz503

+0

ठीक है, तो एक गैर एआरसी env, '' MyObject * obj = [[MyObject alloc] init]; '' एक ऑटोरेलीज पूल के अंदर एक मेमोरी रिसाव होगा लेकिन एआरसी एनवी पर, कंपाइलर स्वचालित रूप से रिलीज कॉल के लिए रिलीज कॉल जोड़ता है वस्तु या फिर यह स्मृति स्मृति रिसाव क्यों नहीं है? – Teo

6

(। अधिकतर बस कुछ अतिरिक्त पृष्ठभूमि दे रही है; @ Kibitz503 सही जवाब के लिए आप हो रही है)

@autoreleasepool { 

    MyObject *obj = [[MyObject alloc] init]; // no autorelease call here 

    /* use the object*/ 
    //.... 
    // in the end it should get deallocated because it's lifespan ends, right? 
    // so why do we need to call autorelease then?! 
} 

पुनश्च: कृपया मुझे बताओ नहीं है कि एआरसी की वजह से हम डॉन ' कुछ चीजों को करने की जरूरत नहीं है क्योंकि एआरसी उनका ख्याल रखता है। मैं इसके बारे में पूरी तरह से अवगत हूं, लेकिन मैं स्मृति प्रबंधन के तंत्र को समझने के लिए कुछ ही क्षणों के लिए एआरसी को छोड़ना चाहता हूं।

ठीक है, आइए एआरसी पर विचार न करें। उपरोक्त में, एआरसी के बिना, obj को हटाया नहीं जाएगा। केवल इसलिए कि एआरसी अतिरिक्त release कॉल संभवतः को हटा दिया जाता है (आपका उदाहरण दिया गया है, हमें वास्तव में कोई जानकारी नहीं है क्योंकि हम नहीं जानते कि use the object में क्या होता है)।

जैसा कि @ किबिट्ज 503 बताता है, "रिलीज" का मतलब "विलुप्त होना" नहीं है। ब्लॉक के अंत में, ऑटोरेलीज पूल नाली, जिसका मतलब है कि किसी भी लंबित autorelease कॉल ब्लॉक के अंत में release के रूप में भेजे जाते हैं। यदि यह 0 को बनाए रखने वाली वस्तु तक पहुंचने वाली वस्तु की ओर जाता है, तो इसे हटा दिया जाता है।

लेकिन क्या उपर्युक्त ब्लॉक में है या नहीं, एआरसी के बिना यह एक रिसाव है।

+0

रिसाव के बारे में अच्छी स्पष्टीकरण। यह इसके चारों ओर लपेटकर ऑटोरेलीज पूल के साथ या उसके बिना एक रिसाव है! – Kibitz503

+0

क्या इसका मतलब यह है कि यदि मैं एआरसी का उपयोग करता हूं और 'autautleasepool {} '' के बाहर कहीं से ऑब्जेक्ट जारी करता हूं तो ऑब्जेक्ट अभी भी @autoreleasepool ब्लॉक के अंत तक मौजूद है? – confile

+0

यह कोड पर निर्भर करता है। ऑटोरेलीजपूल ब्लॉक के अंत में, उस ब्लॉक में बनाए गए सभी लंबित ऑटोरेलीज़ भेजे जाते हैं। मुझे नहीं पता कि आपके ऑब्जेक्ट में "ऑब्जेक्ट रिलीज़" का क्या अर्थ है। आप शायद एक विशिष्ट कोड उदाहरण एक साथ रखना चाहते हैं और एक नया प्रश्न पोस्ट करना चाहते हैं। –

0

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

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