2013-06-10 17 views
5

मैं अगले कोड है। जब मैं ऐप लॉन्च करता हूं जो पहले viewDidload पर जाता है, तो इसे डाउनलोड करने के बाद viewDidDisappear पर जाता है।removeObserver काम नहीं कर रहा

लेकिन मेरे ऐप के दौरान मैं फिर से डेटा डाउनलोड करता हूं और notification: NSDownloadComplete पोस्ट करता हूं। और यह कुलपति में यह काम है, लेकिन मैं बाद में उपयोग करके हटाया:

[[NSNotificationCenter defaultCenter] removeObserver:self] 

यह कुलपति उपयोग viewDidLoad एक बार शुरुआत & नहीं कर सकते फिर addObserver में।

क्या गलत है? कोई परिणाम नहीं -

संपादित मैं viewWillAppear या viewWillDisappear को विधि addObserver डाल प्रयास करें। मैं viewDidLoad

में

[[NSNotificationCenter defaultCenter] addObserverForName... 

से पहले NSLog(@"addObserver"); जोड़ सकते हैं और

- (void)viewDidDisappear:(BOOL)animated 
{ 
    NSLog(@"removeObserver"); 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
    [super viewDidDisappear:animated]; 
} 

लॉग में लिखने मैं देख रहा हूँ:

2013-06-10 14:32:05.646 myApp[9390:c07] addObserver 
2013-06-10 14:32:06.780 myApp[9390:c07] removeObserver 

क्या गलत?

संपादित 2 आपको लगता है कि पर्यवेक्षक हटा दिया जाना चाहिए, लेकिन यह फिर से addObserver विधि

enter image description here

+3

साथ

self.observer = [[NSNotificationCenter defaultCenter] addObserverForName:NCDownloadComplete object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *n){ // ... }]; 

साथ पर्यवेक्षक जोड़ सकते हैं और इसे हटाने कि कोड की नकल और चिपकाया है? मैंने बस सोचा क्योंकि आपकी 'व्यूडिडलोड' सिर्फ 3 लाइनें हैं और उसके बाद ऐसे बयान हैं जो किसी भी विधि में नहीं हैं। यह मान्य नहीं है;) – HAS

+0

@HAS सभी मेरे काम को छोड़कर ठीक काम करते हैं =) – user2213271

+0

क्षमा करें, लेकिन यह नहीं है;) 'self.activityIndicator.originY = 355.f;' के बाद घुंघराले ब्रेस गलत है। निकालें और आपके पास वैध कोड होगा;) – HAS

उत्तर

24
ऐड से

अलावा/पर्यवेक्षक को दूर कॉल ठीक से संतुलित नहीं किया जा रहा है, पर अन्य उत्तर में बताया गया है, एक और समस्या है।

पर्यवेक्षक को हटाने के लिए आपका कोड गलत है। ब्लॉक-आधारित पर्यवेक्षक के लिए, addObserverremoveObserver पर तर्क के रूप में दिया जाना चाहिए। तो आपको एक संपत्ति

@property(nonatomic, strong) id observer; 

कक्षा में जोड़ना चाहिए। तो फिर तुम

[[NSNotificationCenter defaultCenter] removeObserver:self.observer]; 
+0

हाँ, यह मेरी समस्या का समाधान करता है। धन्यवाद =) – user2213271

+0

धन्यवाद मार्टिन, आपका समाधान इतना अच्छा काम करता है। – Wilson

3

पैटर्न आप उपयोग कर रहे सही नहीं है में ब्लॉक चलाने के देख सकते हैं। आपको पर्यवेक्षक को viewDidAppear: में जोड़ना चाहिए और इसे viewDidDisappear: में हटा देना चाहिए।

+1

में ऑब्सर्वर को हटाएं या 'viewWillAppear' में पर्यवेक्षक जोड़ें: –

+1

@ e1985 सहायता नहीं करते हैं। और viewWillAppear: – user2213271

5

क्या ई 1 9 85 एक्सपोज़ करने का प्रयास कर रहा है यह है कि आपकी addObserver और removeObserver कॉल ठीक से संतुलित नहीं हैं। viewDidLoad को वीसी प्रारंभिक के बाद केवल एक बार बुलाया जाता है, लेकिन viewDidDisappear प्रत्येक बार दृश्य नियंत्रक को स्क्रीन से हटा दिया जाता है।

आपकी समस्या का समाधान करने के लिए आप अपने addObserver और removeObserver कॉल, या तो dealloc में viewDidLoad और दूसरे में उन्हें बनाने के द्वारा, या संतुलन होना चाहिए - के रूप में e1985 सुझाव दिया - viewDidAppear: और viewDidDisappear: में।

संपादित: ठीक है, आपकी समस्या (addObserver:selector:name:object: के रूप में यदि आप पहले तर्क के रूप में self पारित करना होगा) तथ्य यह है कि आप addObserverForName:object:queue:usingBlock: उपयोग कर रहे हैं जो self पर्यवेक्षक के रूप में पंजीकृत नहीं है से आता है तो।

तो आपके मामले में, [[NSNotificationCenter defaultCenter] removeObserver:self]; कुछ भी नहीं है क्योंकि self एक पर्यवेक्षक नहीं है।

वापसी मूल्य

एक अपारदर्शी वस्तु प्रेक्षक के रूप में कार्य करने के लिए: आप के बजाय removeObserver:addObserverForName:object:queue:usingBlock: की वापसी मूल्य पर फोन करना चाहिए, जैसा दिखाया गया है in the doc

तो अपने कोड की तरह कुछ लग रहा है चाहिए:

// header file .h 
@interface SplashViewVC : UIViewController 

@property (strong, nonatomic) id downloadCompleteObserver; 

@end 

// implementation file .m 
@implementation SplashViewVC 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // [...] snip 

    self.downloadCompleteObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NCDownloadComplete object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *n){ 
     NSInteger errorCode = [n.userInfo[@"errorCode"] integerValue];   
     [self.activityIndicator stopAnimating]; 
     if (errorCode == ERROR_CODE_NO_CONNECTION) { 
      UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Some problem with server" delegate:self cancelButtonTitle:@"try again" otherButtonTitles:nil]; 
      [alertView show]; 
     } else if (errorCode == 0) { 
      [self dismissViewControllerAnimated:YES completion:nil]; 
     } 
    }]; 
    [self downloadData]; 
} 

// [...] snip 

- (void)dealloc 
{ 
    [[NSNotificationCenter defaultCenter] removeObserver:self.downloadCompleteObserver]; 
    [super dealloc]; 
} 

@end 
+0

में मदद न करें IDDEpepear में आगे बढ़ें: और कोई परिणाम = ( – user2213271

+0

कृपया समस्या को और स्पष्ट रूप से समझाएं। "काम नहीं कर रहा है"? –

+0

मैं स्क्रीन जोड़ता हूं जहां आप उस ऑब्जेक्ट को हटा सकते हैं जिसे निकालने के बाद कॉल किया जाता है। – user2213271

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