2009-05-26 6 views
29

सही उदाहरण:मुझे सुपर-डिलोक को अंतिम बार क्यों कॉल करना है, और पहले नहीं?

- (void)dealloc { 
    [viewController release]; 
    [window release]; 
    [super dealloc]; 
} 

गलत उदाहरण:

- (void)dealloc { 
    [super dealloc]; 
    [viewController release]; 
    [window release]; 
} 

Althoug alsmost अन्य सभी मामलों में जब एक विधि मैं पहली बार सुपर की विधि कार्यान्वयन कहेंगे अधिभावी, इस मामले सेब में हमेशा [सुपर dealloc कॉल ] अंततः। क्यूं कर?

उत्तर

54

यह सिर्फ एक दिशानिर्देश है। आप [super dealloc] के बाद अन्य निर्देशों को कॉल कर सकते हैं। हालांकि आप सुपरक्लास के चर का उपयोग नहीं कर सकते हैं क्योंकि जब आप [super dealloc] पर कॉल करते हैं तो उन्हें रिलीज़ किया जाता है। अंतिम पंक्ति में सुपरक्लास को कॉल करना हमेशा सुरक्षित रहता है।

इसके अलावा केवीओ और निर्भर (ट्रिगर) चाबियां दुष्प्रभाव उत्पन्न कर सकती हैं अगर वे पहले से ही जारी किए गए सदस्य चर से वंचित हैं।

+5

एआरसी के साथ, आपको '[सुपर डेलोक]' बिल्कुल कॉल करने की आवश्यकता नहीं है, जब आप ऐसा करते हैं तो यह एक कंपाइलर त्रुटि उत्पन्न करता है। – teradyl

12

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

class X { 
    private Map foo; 

    function __construct() { 
     foo = new Map(); 
    } 

    function __destruct() { 
     foo.free; 
    } 
} 

class Y extends X { 
    function __construct() { 
     super.__construct(); 
     map.put("foo", 42); 
    } 

    function __destruct() { 
     super.__destruct(); 
     if (map.containsKey("foo")) { // boooooooooom! 
      doSomething(); 
     } 
    } 
} 

आप अपने कोड में इस समस्या का सामना कर सकते नहीं, क्योंकि "आप जानते हैं कि आप क्या कर रहे हैं", लेकिन यह ऐसी चीजों को न करने के लिए एक सुरक्षित और समग्र बेहतर अभ्यास है।

+1

कोई भी विस्तार करने की देखभाल करता है कि यह क्यों कम किया गया था? – n3rd

+4

कोई भी विस्तार करने की देखभाल करता है कि यह क्यों उखाड़ फेंका गया था? –

+0

मेरा अनुमान है क्योंकि यह कम से कम आंशिक रूप से प्रश्न का उत्तर देता है। दूसरी तरफ एक डाउनवोट आमतौर पर तात्पर्य है कि जवाब अनुपयोगी था या सिर्फ सादा गलत था। अगर यह गलत था तो मुझे यह जानना बहुत पसंद होगा कि मैं अपनी गलती से क्यों सीख सकता हूं। या आप सिर्फ ध्रुवीय थे? – n3rd

5

[सुपर डेलोक] आपके ऑब्जेक्ट द्वारा उपयोग की जाने वाली मेमोरी को खाली कर रहा है, जिसमें पॉइंटर्स को नियंत्रक और विंडो देखने के लिए शामिल किया गया है। उन्हें मुक्त करने के बाद वेरिएबल्स का जिक्र करना सबसे अच्छा है।

this answer देखें।

1

आप व्यावहारिक रूप से लगभग [super dealloc] अंत में हैं क्योंकि यह सुपरक्लास के चर को मुक्त करता है और अब उन्हें एक्सेस नहीं किया जा सकता है।

एक अपवाद यह है कि यदि आपके पास UITableViewController का उप-वर्ग है जो किसी अन्य वर्ग का उपयोग अपने तालिका दृश्य प्रतिनिधि के रूप में कर रहा है। उस स्थिति में आपको [super dealloc] के बाद तालिका दृश्य प्रतिनिधि को रिलीज़ करना होगा क्योंकि तालिका दृश्य तालिका दृश्य प्रतिनिधि का संदर्भ दे रहा है और तालिका दृश्य को पहले रिलीज़ करना होगा।

+1

क्या आप अपने अपवाद का थोड़ा और विवरण दे सकते हैं? यह मेरे लिए थोड़ा गलत लगता है। –

+1

@ मार्क: मुझे भी गलत लगता है। आम तौर पर आप चक्र को बनाए रखने से बचने के लिए पहले स्थान पर प्रतिनिधि को भी नहीं बनाए रखेंगे। –

2

यहां वास्तविक उदाहरण है जहां [सुपर डेलोक] आखिरी होना चाहिए, अन्यथा कॉल को हटाने के लिए कॉल क्रैश का कारण बन जाएगा। मुझे यकीन नहीं है कि NSOutputStream के निकालें FromRunLoop के अंदर क्या होता है, लेकिन ऐसा लगता है कि इस मामले में 'स्वयं' तक पहुंच है।

सेटअप:

[outputStream setDelegate:self]; 
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 

dealloc:

- (void)dealloc { 
    if (outputStream) { 
     [outputStream close]; 
     [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] 
           forMode:NSDefaultRunLoopMode]; 
     [outputStream release]; 
     outputStream = nil; 
    } 
    delegate = nil; 
    [super dealloc]; // must be last! 
} 
1

tableView प्रतिनिधि को संदर्भित नहीं होगा [पिछले पोस्ट करने के लिए] जारी यह खुद प्रतिनिधि है के लिए जिम्मेदार हो सकता है? मुझे लगता है कि इसे सेट करते समय इसे बनाए रखा जाएगा (ताकि आप इसे रिलीज़ या ऑटोरेलीज़ कर सकें) और यह स्वयं का ख्याल रखेगा?

ओपी प्रश्न के लिए, अगर मैं निर्माण कर रहा हूं और सुपर विनाश कर रहा हूं तो मैं हमेशा सुपर कॉल करूँगा।मैं इसके बारे में सोचता हूं "मैं सुपर बिल्ड करना चाहता हूं जो चाहता है ताकि मैं उस पर निर्माण कर सकूं, और मैं अपने बाद साफ होने के बाद सुपर को फाड़ना चाहता हूं।" वस्तुतः सभी कॉल जो मैं उपयोग कर रहा हूं, निर्माण कर रहे हैं, हालांकि, डेलोक को छोड़कर, इसलिए आप इसे हमेशा मेरे डेलोक कोड में देख पाएंगे।