क्या एक स्विफ्ट कार्यक्रम में ऑटोरेलिस्पूल का उपयोग करना आवश्यक है?


95

पृष्ठ 17 पर इस WWDC14 प्रस्तुति के , यह कहता है

उद्देश्य-सी के साथ काम करना? अभी भी ऑटोरेलिज पूल का प्रबंधन करना है
ऑटोरेलिजपूल {/ * कोड * /}

इसका क्या मतलब है? क्या इसका मतलब है कि अगर मेरे कोड आधार में कोई ऑब्जेक्टिव-सी फाइलें नहीं हैं, तो क्या autoreleasepool {}यह अनावश्यक है?

में एक संबंधित सवाल का एक जवाब है, वहाँ एक उदाहरण है जहां है autoreleasepoolउपयोगी हो सकता है:

- (void)useALoadOfNumbers {
    for (int j = 0; j < 10000; ++j) {
        @autoreleasepool {
            for (int i = 0; i < 10000; ++i) {
                NSNumber *number = [NSNumber numberWithInt:(i+j)];
                NSLog(@"number = %p", number);
            }
        }
    }
}

यदि ऊपर दिए गए कोड को स्विफ्ट में autoreleasepoolगिरा दिया गया है, तो क्या स्विफ्ट यह जानने के लिए पर्याप्त स्मार्ट होगा कि numberचर को पहले के बाद जारी किया जाना चाहिए }(जैसे कुछ अन्य भाषाएं करती हैं)?


1
प्रतीत होता है कि autoreleasepoolस्विफ्ट में कोई दस्तावेज नहीं है । मैंने आपके प्रश्न पर विस्तार किया और देव मंचों में पूछा
हारून ब्रेजर

जवाबों:


197

autoreleasepoolपैटर्न जब लौटने स्विफ्ट में प्रयोग किया जाता है autoreleaseवस्तुओं (अपने ऑब्जेक्टिव-सी कोड या कोको वर्गों का उपयोग या तो द्वारा बनाई गई)। autoreleaseबहुत इसे पसंद स्विफ्ट कार्यों में पैटर्न ऑब्जेक्टिव-सी में करता है। उदाहरण के लिए, अपनी पद्धति (त्वरित NSImage/ UIImageऑब्जेक्ट) के इस स्विफ्ट प्रतिपादन पर विचार करें :

func useManyImages() {
    let filename = pathForResourceInBundle

    for _ in 0 ..< 5 {
        autoreleasepool {
            for _ in 0 ..< 1000 {
                let image = NSImage(contentsOfFile: filename)
            }
        }
    }
}

यदि आप इसे इंस्ट्रूमेंट्स में चलाते हैं, तो आपको निम्नलिखित की तरह एक आबंटन ग्राफ़ दिखाई देगा:

ऑटोरेलिज़पूल के साथ

लेकिन अगर आप इसे ऑटोरेलिज पूल के बिना करते हैं, तो आप देखेंगे कि शिखर मेमोरी का उपयोग अधिक है:

ऑटोरेलिज़पूल के बिना

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

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


2
इन सभी सवालों पर, आप अपनी खुद की कक्षा लिख ​​सकते हैं, और क्या यह एक printlnमें है deinit, और वस्तुओं के डील-डौल होने पर इसे ठीक से सत्यापित करना काफी आसान हो जाता है। या इसे साधनों में देखें। आपके प्रश्न के उत्तर में, ऐसा प्रतीत होता है कि स्विफ्ट ऑब्जेक्ट्स को +1 रिटेन काउंट (ऑटोरेलिज़ ऑब्जेक्ट्स नहीं) के साथ फ़ंक्शंस से लौटाया जाता है, और कॉलर मूल रूप से उस बिंदु से स्वामित्व का प्रबंधन करेगा (उदाहरण के लिए, यदि और लौटी हुई वस्तु दायरे से बाहर हो जाती है, तो) यह तुरंत निपटा जाता है, एक ऑटोरेलिज़ुलप में नहीं रखा जाता है)।
राब

3
@StevenHernandez एक ऑटोरेलिज़ पूल का लीक से बहुत कम लेना-देना है। एक रिसाव असंबंधित वस्तु के कारण होता है। दूसरी ओर, ऑटोरेलिज पूल केवल वस्तुओं का एक संग्रह है, जिसके लिए पूल को हटाए जाने तक रिलीज को स्थगित कर दिया जाता है। पूल नियंत्रित नहीं करते हैं कि कुछ निपटाया गया है या नहीं, बल्कि इस तरह के निपटारे का समय है। मानचित्र दृश्य देखें, आप नियंत्रित नहीं कर सकते कि यह क्या करता है (स्मृति का उपयोग करता है, लेकिन सही रिसाव नहीं) और न ही कुछ भी नहीं है अगर कोई वास्तविक रिसाव था (और मुझे किसी भी महत्वपूर्ण मानचित्र दृश्य लीक के बारे में पता नहीं है, हालांकि ऐतिहासिक रूप से वहाँ रहे हैं यादृच्छिक, UIKit में मामूली लीक)।
रॉब

2
@ मैम हां, मैंने ऐसा ही व्यवहार देखा। इसलिए मैंने अपने अभ्यास को NSImage/ UIImageवस्तुओं के साथ दोहराया और समस्या को और अधिक लगातार प्रकट किया (और, स्पष्ट रूप से, यह समस्या का एक अधिक सामान्य उदाहरण है, क्योंकि बड़ी वस्तुओं के साथ काम करते समय शिखर मेमोरी का उपयोग अक्सर केवल समस्याग्रस्त होता है; इसका एक व्यावहारिक उदाहरण हो सकता है; एक नियमित छवियों का एक गुच्छा आकार)। मैंने ऑब्जेक्ट-सी कोड को कॉल करने वाले व्यवहार को भी पुन: उत्पन्न किया जो स्पष्ट रूप से ऑटोरेलिज़ ऑब्जेक्ट बनाता है। मुझे गलत मत समझिए: मुझे लगता है कि हमें ऑब्जेक्टिव-सी से कम बार स्विफ्ट में ऑटोरेलिज पूल की जरूरत है, लेकिन इसमें अभी भी एक भूमिका निभानी है।
रोब

1
मुझे एक उदाहरण मिला जो काम करता है! बस NSBundle के pathForResource:ofType:बार-बार कॉल करें ।
मैट

1
मेरा pathForResource:ofType:उदाहरण अब Xcode 6.3 / स्विफ्ट 1.2 में काम नहीं करता है। :)
मैट

4

यदि आप इसे समान उद्देश्य-सी कोड में उपयोग करेंगे, तो आप इसे स्विफ्ट में उपयोग करेंगे।

स्विफ्ट यह जानने के लिए पर्याप्त स्मार्ट होगा कि नंबर चर पहले के बाद जारी किया जाना चाहिए}

केवल यदि Objective-C करता है। दोनों कोको स्मृति प्रबंधन नियमों के साथ काम करते हैं।

बेशक एआरसी जानता है कि numberलूप के उस पुनरावृत्ति के अंत में गुंजाइश से बाहर हो जाता है, और यदि यह इसे बनाए रखता है, तो यह इसे वहां जारी करेगा। हालाँकि, यह आपको यह नहीं बताता है कि क्या वस्तु को ऑटोरेलिज्ड किया गया था, क्योंकि एक ऑटोरेल्ड उदाहरण वापस आ -[NSNumber numberWithInt:] सकता है या नहीं । ऐसा कोई तरीका नहीं है जिसे आप जान सकें, क्योंकि आपके पास स्रोत तक पहुंच नहीं है -[NSNumber numberWithInt:]


1
यदि स्विफ्ट इसके लिए ऑब्जेक्टिव-सी के समान व्यवहार करता है, तो प्रस्तुति में "ऑब्जेक्टिव-सी के साथ काम करना" का उल्लेख क्यों किया गया है? विशेष रूप से?
एथन

9
@ ईथन ऐसा प्रतीत होता है कि देशी स्विफ्ट ऑब्जेक्ट ऑटोरेलिज़ ऑब्जेक्ट नहीं हैं, और autoreleasepoolनिर्माण पूरी तरह से अनावश्यक है। लेकिन अगर आपका स्विफ्ट कोड ऑब्जेक्टिव-सी ऑब्जेक्ट्स (कोको ऑब्जेक्ट्स सहित) को हैंडल कर रहा है, तो वे ऑटोरेलिज पैटर्न का पालन करते हैं, और इस तरह autoreleasepoolनिर्माण उपयोगी हो जाता है।
रोब

मुझे लगता है कि "ऑटोरेलिज़पूल आपको स्पष्ट रूप से प्रबंधित करने की अनुमति देता है जब ऑटोरेलिज़ ऑब्जेक्ट्स स्विफ्ट में निपटाए जाते हैं" लेकिन मैं क्यों चाहूंगा? संकलनकर्ता मेरे लिए ऐसा क्यों नहीं कर सकता / सकती? मुझे वीएम को विशाल स्ट्रिंग जोड़तोड़ के तंग पाश में छत से गुजरने के लिए अपने स्वयं के ऑटोरेलेज़पूल को जोड़ना पड़ा। यह मेरे लिए स्पष्ट था कि इसे कहाँ जोड़ा जाना चाहिए, और इसने पूरी तरह से काम किया। कंपाइलर ऐसा क्यों नहीं कर सका? क्या कंपाइलर को इससे अच्छा काम करने के लिए होशियार बनाया जा सकता है?
वॉनलोस्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.