2012-04-06 14 views
16

मैं आमतौर पर नीचे दिए गए नमूना तरह NSNotification का उपयोग एक बेहतर तरीका है:कौन सा दूर करने के लिए अधिसूचना पर्यवेक्षक

viewDidLoad में:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(foo:) name:kName1 object:nil]; 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(bar:) name:kName2 object:nil]; 

viewDidUnload में और dealloc:

[[NSNotificationCenter defaultCenter] removeObserver:self]; 

लेकिन एक दोस्त मुझे बताया कि मुझे [[NSNotificationCenter defaultCenter] removeObserver:self]; का उपयोग नहीं करना चाहिए क्योंकि यह सुपर क्लास समेत सभी पर्यवेक्षकों को हटा देगा। उन्होंने मुझे पर्यवेक्षक को एक-एक करके हटाने के लिए निम्नलिखित कोड का उपयोग करने का सुझाव दिया।

[[NSNotificationCenter defaultCenter] removeObserver:self name:kName1 object:nil]; 
[[NSNotificationCenter defaultCenter] removeObserver:self name:kName2 object:nil]; 

मैं ASIHttpRequest लाइब्रेरी की कोड (https://github.com/pokeb/asi-http-request) देख लिया है। यह मेरे दोस्तों के सुझाव का पालन करता है।

मैं जानना चाहता हूं कि मेरा मित्र सही है या नहीं? मेरी राय में, चूंकि वर्तमान उदाहरण अनलोड या डेलोक होगा, सुपर क्लास की अधिसूचना भी बेकार है। और क्या कोई सिस्टम UIViewController subclass उपयोग अधिसूचना है?

+0

इसका अर्थ यह है कि यह "सुपर क्लास 'पर्यवेक्षक" को हटा देगा? एक पर्यवेक्षक एक वस्तु उदाहरण नहीं है। यदि इसे हटा दिया जा रहा है तो यह _must_ को सभी अधिसूचनाओं से खुद को अनधिकृत कर देगा, भले ही वे सुपर क्लास कोड में पंजीकृत हों। – MrTJ

+0

@MrTJ मेरा मतलब अधिसूचना पर्यवेक्षक है जो सुपर की विधि में जोड़ा जाता है। हो सकता है कि क्लास इंस्टेंस के पिता को कुछ नोटिफिकेशन भी देखने की ज़रूरत हो, जब बच्चे का दृश्यडिउडलोड विधि कहा जाता है। – tangqiaoboy

+0

हो सकता है, हो सकता है।यदि आप सुरक्षा में अपंजीकृत करना चाहते हैं तो सुरक्षा के लिए भी मैं दूसरी विधि (प्रति पर्यवेक्षक अनियंत्रण) – MrTJ

उत्तर

12

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

विशिष्ट नामों के साथ अवलोकन को हटाने का अच्छा अभ्यास है और शुरुआत से ही किया जाना चाहिए।

+0

धन्यवाद। तो हम '[[NSNotificationCenter defaultCenter] removeObserver: self] का उपयोग कर सकते हैं;' 'dealloc' विधि में, लेकिन' viewDidUnload' विधि में नहीं, है ना? – tangqiaoboy

+0

हां, 'निकालें ऑब्सर्वर:' का उपयोग डेलोक के बाहर नहीं किया जाना चाहिए। लेकिन मैं विशेष रूप से प्रत्येक अवलोकन को हटाना पसंद करता हूं, इसलिए मैं 'removeObserver:' का उपयोग नहीं करता हूं। मैं अपनी सभी सूचनाओं के लिए विशिष्ट विधि 'removeObserver: name: object:' का उपयोग करता हूं। मैं अपना कोड बहुत विशिष्ट रखना चाहता हूं। –

7

आप सभी अधिसूचना आप का उपयोग को दूर करना चाहते हैं,

[[NSNotificationCenter defaultCenter] removeObserver:self]; 

आप आप का उपयोग एक विशेष सूचना को निकालने चाहते हैं,

[[NSNotificationCenter defaultCenter] removeObserver:self name:kName1 object:nil]; 

जब आप किसी पूर्व सूचना के पहले की जरूरत होती नहीं रह गया दृष्टिकोण सरल है।

0

मैं पहली बार उपयोग करता हूं, मैंने कभी सोचा नहीं कि यह सही था या नहीं। यदि डेलोक को बुलाया जा रहा है, तो ऑब्जेक्ट (सुपर भी) को वैसे भी हटा दिया जा रहा है। जो आप निश्चित रूप से नहीं चाहते हैं वह एनएसएनोटिफिकेशन को एक आवंटित उदाहरण में भेजा जा रहा है।

1

जैसे वस्तु दूर जा रही है, विधि में [[NSNotificationCenter defaultCenter] removeObserver:self]; का उपयोग करना सुरक्षित है।

ViewDidUnload विधि में, आप बेहतर एक एक करके प्रत्येक पर्यवेक्षक को निकालना चाहते हैं के रूप में नियंत्रक के लिए एक संदर्भ अभी भी चारों ओर है (और अपने इसी viewDidLoad उन्हें में सभी वापस जोड़ने चाहिए)।

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