12

कहा जाता है मैं उलझन में हूं कि पर्यवेक्षक को निम्न कोड में क्यों नहीं हटाया जाता है। मेरी viewDidAppear में मैं निम्नलिखित है:NSNotificationCenter से पर्यवेक्षक को क्यों नहीं हटाया जाता है: addObserverForName: useBlock को

-(void)viewDidAppear:(BOOL)animated{ 

id gpsObserver = [[NSNotificationCenter defaultCenter] 
          addObserverForName:FI_NOTES[kNotificationsGPSUpdated] 
          object:nil 
          queue:[NSOperationQueue mainQueue] 
          usingBlock:^(NSNotification *note){ 

           NSLog(@"run once, and only once!"); 

       [[NSNotificationCenter defaultCenter] removeObserver:gpsObserver]; 

     }]; 

} 

पर्यवेक्षक कभी नहीं हटा दिया जाता है और बयान हर बार अधिसूचना बाहर भेज दिया जाता उत्पादन होता है। क्या कोई मार्गदर्शन प्रदान कर सकता है?

उत्तर

28

जब ब्लॉक को addObserverForName: द्वारा स्टैक पर धक्का दिया जाता है तो विधि अभी तक वापस नहीं आई है इसलिए जीपीएस ऑब्सर्वर शून्य (एआरसी के तहत) या कचरा/अपरिभाषित (एआरसी के तहत नहीं) है। __block का उपयोग करके चर घोषित करें और यह काम करना चाहिए।

__block __weak id gpsObserver; 

gpsObserver = [[NSNotificationCenter defaultCenter] 
          addObserverForName:FI_NOTES[kNotificationsGPSUpdated] 
          object:nil 
          queue:[NSOperationQueue mainQueue] 
          usingBlock:^(NSNotification *note){ 

           NSLog(@"run once, and only once!"); 

       [[NSNotificationCenter defaultCenter] removeObserver:gpsObserver]; 

     }]; 

मैं सुनिश्चित करने के लिए (मैट के जवाब के अनुसार) कोई स्मृति रिसाव होती है एक __weak जोड़ दिया है। कोड का परीक्षण नहीं किया गया।

+0

समझ में आता है और अपेक्षा के अनुरूप काम करता है कि; आपके सहयोग के लिए धन्यवाद। – warpedspeed

11

मुझे लगता है कि वास्तव में एक स्मृति रिसाव है जब तक पर्यवेक्षक को __block और __weak दोनों चिह्नित किया जाता है। यह सुनिश्चित करने के लिए उपकरण का प्रयोग करें कि self अधिक नहीं किया जा रहा है; मैं शर्त लगा सकता हूँ कि यह है। लेकिन यह ठीक से काम करता (मेरी वास्तविक कोड से):

__block __weak id observer = [[NSNotificationCenter defaultCenter] 
    addObserverForName:@"MyMandelbrotOperationFinished" 
    object:op queue:[NSOperationQueue mainQueue] 
    usingBlock:^(NSNotification *note) { 
     // ... do stuff ... 
     [[NSNotificationCenter defaultCenter] 
      removeObserver:observer 
      name:@"MyMandelbrotOperationFinished" 
      object:op]; 
}]; 
+0

मुझे यह पसंद आएगा अगर वे समकक्ष विधि पेश करेंगे जो आपको वास्तव में पर्यवेक्षकों को बनाए रखने की आवश्यकता नहीं है बल्कि चयनकर्ताओं के बजाय ब्लॉक का उपयोग करके स्वयं को एक के रूप में उपयोग करें। – Eugene

+2

यदि आप इसे 'NSNotificationCenter' से हटाने के बाद इसे 'nil' पर सेट करते हैं तो आपको' पर्यवेक्षक '' __weak' बनाने की आवश्यकता नहीं है। मैंने इसे इंस्ट्रूमेंट्स के साथ चेक किया है। –

+0

यह कोड का एक अच्छा टुकड़ा है, महोदय। – Andy

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