5

मेरे पास ViewController कक्षा है जिसमें एक संपत्ति है जो मॉडल है जिसे मैं मॉडल परिवर्तन पर गुणों के रूप में देखना चाहता हूं। मेरे मॉडल ऑब्जेक्ट में मेरे पास एक ऐसी संपत्ति है जो समय-समय पर मेरे आवेदन की पृष्ठभूमि में अपडेट की जाती है। जैसा कि यह अद्यतन होता है, मुझे अपने ViewController के भीतर कोड निष्पादित करने की आवश्यकता है।मुझे हटाए जाने वाले ऑब्सर्वर को कब कॉल करना चाहिए: केपीपाथ को एक सतत मॉडल क्लास को देखकर एक क्लोजिंग व्यू कंट्रोलर क्लास के भीतर से?

ऐसा करने के लिए, मैं अपने ViewControllerviewDidLoad विधि के भीतर से अपने मॉडल पर एक पर्यवेक्षक बना देता हूं।

[ModelObject addObserver:self 
       forKeyPath:@"State" 
       options:NSKeyValueObservingOptionNew 
       context:nil]; 

आप देख सकते हैं, यह कोई खास बात है और प्रेक्षण विधि बर्ताव करता है के रूप में यह इतने लंबे समय के रूप में मैं दृश्य मेरी स्क्रीन पर प्रदर्शित छोड़ देना चाहिए। यदि मैं उपरोक्त दृश्य को मूल दृश्य से हटा देता हूं, तो मुझे EXC_BAD_ACCESS त्रुटि संदेश मिलता है जब मेरा ModelObject उदाहरण Mode संपत्ति परिवर्तन होता है। विशेष रूप से, मेरा ऐप Mode प्रॉपर्टी को अपडेट करने वाली लाइन पर क्रैश हो जाता है और मुझे मॉडलऑब्जेक्ट इंस्टेंस के भीतर कोड की निम्न पंक्ति पर अधिकतर बेकार EXC_BAD_ACCESS प्राप्त होता है।

//This is located in a method that periodically toggles the value of "State" 
[self setState: 2]; 

मैं इस समस्या का समाधान ग्रहण करेंगे मेरी ViewController भीतर कहीं से [ModelObject removeObserver: self forKeyPath:@"State"] कॉल करने के लिए जब यह निकाल दिया जाता है कि उसे अपने जनक subview सरणी है से है। हालांकि, मैंने अपने viewDidUnload विधि के भीतर कोड की उस पंक्ति को जोड़ा है लेकिन मुझे viewDidUnload विधि नहीं कहा जा रहा है। मुझे यकीन नहीं है कि यह सही जगह है, लेकिन इसे कुछ जगहों पर जाना होगा।

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

उत्तर

9

में इसे निकाल देना चाहिए मैं आम तौर पर viewWillAppear: और viewWillDisappear: में addObserver: और removeObserver: डाल करने के लिए पसंद करते हैं। मुझे लगता है कि ये viewDidLoad और viewDidUnload से अधिक विश्वसनीय बुकेंड हैं।

+0

आह, सही। मेरा आवेदन अब काम कर रहा है जैसा इसे करना चाहिए। – RLH

+0

मैं इस समाधान को दूसरा करता हूं। 'viewDidUnload:' को कॉल किया जाता है जब एक स्मृति चेतावनी प्राप्त होती है और 'viewDidLoad: 'जैसा कोई नहीं सोच सकता है। –

+0

यह समस्याग्रस्त है जब यूनिट-परीक्षण दृश्य नियंत्रक को दृश्य पदानुक्रम में जोड़ने के बिना। –

1

आप दृश्य नियंत्रक के -dealloc

+1

आपको केवल यह करना चाहिए यदि आपने स्वयं को ऑब्जेक्ट सृजन ('init ...' और 'awakeFromNib') पर पर्यवेक्षक के रूप में जोड़ा है। अन्यथा आप असंतुलन प्राप्त कर सकते हैं। उदाहरण के लिए, 'viewDidLoad' को' dealloc' से कई बार बुलाया जा सकता है। –

+0

हाँ, यह निश्चित रूप से सच है, और यह हमेशा होता है कि मैं इसे कैसे करता हूं। – jsd

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