2011-09-03 12 views
198

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

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    [observer registerObject:self]; 
} 

उपयोगकर्ता "परिवर्तन भाषा" बटन हिट करते हैं, नई भाषा अपने मॉडल में संग्रहित है और पर्यवेक्षक अधिसूचित किया गया है और इसके पंजीकृत वस्तुओं पर एक updateUi: चयनकर्ता कहते हैं।

यह बहुत अच्छा काम करता है, सिवाय इसके कि जब मेरे पास TabBarController में नियंत्रक दिखाई देते हैं। ऐसा इसलिए है क्योंकि जब टैब बार लोड होता है, तो यह दृश्य आइकन प्रारंभ किए बिना टैब आइकन को अपने बाल नियंत्रकों से प्राप्त करता है, इसलिए viewDidLoad: नहीं कहा जाता है, इसलिए उन दृश्य नियंत्रकों को भाषा परिवर्तन अधिसूचनाएं प्राप्त नहीं होती हैं। इस वजह से, मैंने को init विधि में कॉल किया।

वापस जब मैंने अपने पर्यवेक्षक के साथ पंजीकरण करने के लिए viewDidLoad: का उपयोग किया, तो मैंने पंजीकरण करने के लिए viewDidUnload: का उपयोग किया। चूंकि अब मैं init में पंजीकरण कर रहा हूं, इसलिए dealloc में पंजीकरण रद्द करने के लिए बहुत सारी समझ है।

लेकिन मेरी समस्या यहां है। जब मैं लिख:

- (void) dealloc 
{ 
    [observer unregisterObject:self]; 
    [super dealloc]; 
} 

मैं इस त्रुटि मिलती है:

ARC forbids explicit message send of 'dealloc'

जब से मैं [super dealloc] कॉल करने के लिए सुनिश्चित करने के लिए सुपर-क्लास ठीक से साफ की जरूरत है, लेकिन एआरसी मनाही है कि, मैं अब अटक कर रहा हूँ। क्या मेरी वस्तु मरने पर सूचित होने का कोई और तरीका है?

+0

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

+0

मैंने दाएं और बाएं हाथ विकल्पों के लिए कुछ समान लागू किया। संदेश की आवश्यकता वाले एकमात्र वीसी वर्तमान में प्रदर्शित एक है। अन्य इंटरफ़ेस में परिवर्तन करने के लिए मॉडल को देखें या देखेंडडपियर देखें। शायद ऐसा कुछ बेहतर काम करेगा। –

+0

@BlazejCzapp चूंकि वह एक UITabBarController का उपयोग कर रहा है, और मान लें कि UITabBarController हमेशा पंजीकृत नियंत्रक का संदर्भ रखेगा (जैसा कि मुझे लगता है कि इसके 'बच्चे' नियंत्रकों के साथ मामला है), क्या स्मृति रिसाव अभी भी एक मुद्दा होगा? मैं नहीं देखता कि पंजीकृत नियंत्रक कब आवंटित किया जाएगा। धन्यवाद – Objectif

उत्तर

400

जब एआरसी का उपयोग कर, आप बस फोन नहीं है [super dealloc] स्पष्ट - संकलक (Clang LLVM ARC document, chapter 7.1.2 में वर्णित है) यह तुम्हारे लिए संभालती है:

- (void) dealloc 
{ 
    [observer unregisterObject:self]; 
    // [super dealloc]; //(provided by the compiler) 
} 
+2

यदि दृश्य पर्यवेक्षक का संदर्भ रखता है, और पर्यवेक्षक दृश्य के संदर्भ में हैं, तो हमारे पास एक परिपत्र संदर्भ है। तो दृश्य की संदर्भ संख्या 0 से अधिक है, और 'dealloc' कभी नहीं कहा जाता है। क्या यह dealloc में '[पर्यवेक्षक unregisterObject: self] 'कॉल करने के लिए समझ में आता है? मैं क्या खो रहा हूँ? – user443854

+0

कि काम करना चाहते हैं। कारण पर्यवेक्षक स्वयं नियंत्रक के लिए एक संदर्भ रखता है। जो पहली जगह में बुलाए जाने के डेलोक को रोक देगा – hasan83