निपटाओ स्विफ्ट में


145

मैं एक NSNotificationCenterअधिसूचना को हटाने के लिए, एक दृश्य नियंत्रक के जीवन के अंत में कुछ सफाई करना चाहूंगा । deallocस्विफ्ट कंपाइलर त्रुटि में परिणाम लागू करना :

Cannot override 'dealloc' which has been marked unavailable

स्विफ्ट में किसी वस्तु के जीवन के अंत में कुछ सफाई करने का पसंदीदा तरीका क्या है?

जवाबों:


333
deinit {
    // perform the deinitialization
}

से स्विफ्ट प्रलेखन :

क्लास इंस्टाल करने से ठीक पहले एक डीइन्यूएस्टाइज़र कहा जाता है। आप डीइनिटाइज़र को डीइनिट कीवर्ड के साथ लिखते हैं, इनिट कीवर्ड के साथ इंटेलाइज़र कैसे लिखे जाते हैं। Deinitializers केवल वर्ग प्रकारों पर उपलब्ध हैं।

आमतौर पर आपको मैन्युअल रूप से क्लीन-अप करने की आवश्यकता नहीं होती है जब आपके उदाहरणों को हटा दिया जाता है। हालाँकि, जब आप अपने स्वयं के संसाधनों के साथ काम कर रहे होते हैं, तो आपको कुछ अतिरिक्त सफाई करने की आवश्यकता हो सकती है। उदाहरण के लिए, यदि आप किसी फ़ाइल को खोलने के लिए एक कस्टम क्लास बनाते हैं और उसमें कुछ डेटा लिखते हैं, तो आपको क्लास के उदाहरण से पहले फ़ाइल को बंद करने की आवश्यकता हो सकती है।


45
deinit {
    // perform the deinitialization
}

स्विफ्ट "डीललोक" के लिए सही उत्तर है।

हालांकि, iOS 9 में नए को इंगित करना अच्छा है कि NSNotificationCenter को अब साफ करने की आवश्यकता नहीं है!

https://developer.apple.com/library/content/releasenotes/Foundation/RN-FoundationOlderNotes/index.html#X10_11Notes

NSNotificationCenter

OS X 10.11 और iOS 9.0 NSNotificationCenter और NSDistributedNotificationCenter में अब पंजीकृत पर्यवेक्षकों को सूचनाएं नहीं भेजी जाएंगी, जो डील हो सकती हैं। यदि पर्यवेक्षक को शून्य-कमजोर संदर्भ के रूप में संग्रहीत किया जा सकता है, तो अंतर्निहित भंडारण पर्यवेक्षक को एक शून्य कमजोर संदर्भ के रूप में संग्रहीत करेगा, यदि वैकल्पिक रूप से ऑब्जेक्ट को कमजोर रूप से संग्रहीत नहीं किया जा सकता है (अर्थात इसमें कस्टम अनुरक्षण / रिलीज तंत्र है जो रनटाइम को रोक देगा; ऑब्जेक्ट को कमजोर रूप से संग्रहीत करने में सक्षम होने से) यह ऑब्जेक्ट को गैर-कमजोर शून्यिंग संदर्भ के रूप में संग्रहीत करेगा। इसका मतलब यह है कि पर्यवेक्षकों को अपने निपटान पद्धति में संयुक्त राष्ट्र के पंजीकरण की आवश्यकता नहीं है। अगली सूचना जो उस पर्यवेक्षक को दी जाएगी, वह शून्य संदर्भ का पता लगाएगा और पर्यवेक्षक को स्वचालित रूप से पंजीकृत करेगा। यदि किसी वस्तु को कमजोर रूप से संदर्भित किया जा सकता है, तो सूचनाएँ सौदेबाजी के दौरान पर्यवेक्षक को नहीं भेजी जाएंगी; डीललोक के दौरान सूचनाएं प्राप्त करने का पिछला व्यवहार अभी भी गैर-कमजोर शून्य संदर्भ पर्यवेक्षकों के मामले में मौजूद है। - [NSNotificationCenter addObserverForName: ऑब्जेक्ट: कतार: usingBlock] विधि के माध्यम से ब्लॉक आधारित पर्यवेक्षकों को अभी भी संयुक्त राष्ट्र के पंजीकृत होने की आवश्यकता है जब सिस्टम अब भी इन पर्यवेक्षकों के लिए एक मजबूत संदर्भ नहीं रखता है। समय से पहले ही पर्यवेक्षकों को हटाना (या तो कमजोर संदर्भित या शून्य संदर्भित) अभी भी समर्थित है। CFNotificationCenterAddObserver इस व्यवहार के अनुरूप नहीं है क्योंकि पर्यवेक्षक एक वस्तु नहीं हो सकता है। - [NSNotificationCenter addObserverForName: ऑब्जेक्ट: कतार: usingBlock] विधि के माध्यम से ब्लॉक आधारित पर्यवेक्षकों को अभी भी संयुक्त राष्ट्र के पंजीकृत होने की आवश्यकता है जब सिस्टम अब भी इन पर्यवेक्षकों के लिए एक मजबूत संदर्भ नहीं रखता है। समय से पहले ही पर्यवेक्षकों को हटाना (या तो कमजोर संदर्भित या शून्य संदर्भित) अभी भी समर्थित है। CFNotificationCenterAddObserver इस व्यवहार के अनुरूप नहीं है क्योंकि पर्यवेक्षक एक वस्तु नहीं हो सकता है। - [NSNotificationCenter addObserverForName: ऑब्जेक्ट: कतार: usingBlock] विधि के माध्यम से ब्लॉक आधारित पर्यवेक्षकों को अभी भी संयुक्त राष्ट्र के पंजीकृत होने की आवश्यकता है जब सिस्टम अब भी इन पर्यवेक्षकों के लिए एक मजबूत संदर्भ नहीं रखता है। समय से पहले ही पर्यवेक्षकों को हटाना (या तो कमजोर संदर्भित या शून्य संदर्भित) अभी भी समर्थित है। CFNotificationCenterAddObserver इस व्यवहार के अनुरूप नहीं है क्योंकि पर्यवेक्षक एक वस्तु नहीं हो सकता है।

लेकिन मजबूत संदर्भों के बारे में नीचे दिए गए बिंदुओं पर ध्यान दें, इसलिए आपको किसी भी तरह सफाई की चिंता करनी पड़ सकती है ...?


3
जब तक अधिसूचना ब्लॉक का एक मजबूत संदर्भ नहीं है, तब तक आपको पर्यवेक्षक को हटाना होगा।
टाइगरकोडिंग

+1 प्रेक्षकों की सफाई नहीं करने के लिए। जानना ज़रूरी है! मैं सभी कैप्चरिंग संदर्भों को कमजोर बनाता हूं, इसलिए कभी भी इससे नहीं निपटना चाहिए।
n13

2
अधिसूचना ब्लॉकों को हमेशा प्रलेखन के अनुसार दृढ़ता से संदर्भित किया जाता है। तो: आपको अपनी सूचनाओं को संभालने के लिए ब्लॉकों का उपयोग कर रहे हैं, तो आप है deinit अंदर उनके लिए पंजीकरण रद्द करना।
मार्सबियर

22

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Deinitialization.html

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

कक्षा की परिभाषाएँ प्रति कक्षा में सबसे अधिक एक डिनायस्टाइज़र में हो सकती हैं। डिनायस्टाइज़र कोई पैरामीटर नहीं लेता है और कोष्ठक के बिना लिखा जाता है:

deinit {
    // perform the deinitialization
}

2

निंदा से पहले पर्यवेक्षक को हटाने की आवश्यकता है अन्यथा दुर्घटना होगी। इसका उपयोग करके किया जा सकता है

deinit {
    // perform the deinitialization
    print("deinit")

    removeObserver(self, forKeyPath: kSelectedViewControllerKey, context: nil)
    removeObserver(self, forKeyPath: kSelectedIndexKey, context: nil)

}

-2

विचलित होने से अन्य वर्ग में एक विधि को कॉल करते समय सावधान रहें यह संभवतः दुर्घटना में समाप्त हो जाएगा


1
जरूरी है कि इस मामले में नीचे नहीं होना चाहिए। से रेफरी। डॉक्स : क्योंकि किसी उदाहरण को तब तक नहीं निपटाया जाता है जब तक कि उसके डीइन्यूएलाइज़र को नहीं बुलाया जाता है, एक डीइन्युएलाइज़र उस कॉल के सभी गुणों तक पहुँच सकता है, जो उन गुणों के आधार पर अपने व्यवहार को संशोधित कर सकता है (जैसे कि किसी फ़ाइल का नाम देखना जो उसे करने की आवश्यकता है बंद रहा)।
सुपरजोस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.