2015-07-29 15 views
5

मैं एक साधारण ViewController KVO अनुरूप है और है कि राशि नहीं निकाली जा सकती उस में निम्नलिखित:आईओएस KVO - एक पर्यवेक्षक

- (void) viewDidAppear:(BOOL)animated 
    { 
     [super viewDidAppear:animated]; 



     [self addObserver:self forKeyPath:@"importStuff" options:0 context:NULL]; 
     [self addObserver:self forKeyPath:@"importStuffFailed" options:0 context:NULL]; 
     } 

    - (void) viewWillDisappear:(BOOL)animated 
    { 
     [super viewWillDisappear:animated]; 

     [self removeObserver:self forKeyPath:@"importStuff"]; 
     [self removeObserver:self forKeyPath:@"importStuffFailed"]; 
     } 

मुद्दे im होने कभी कभी उपयोगकर्ता निम्न त्रुटि रिपोर्ट कर रहे हैं वह यह है कि:

Cannot remove an observer <MyViewController 0x145d0c8d0> for the key path "importStuff" from <MyViewController 0x1741b2280> because it is not registered as an observer. 

addObserver कॉल को कोड में कहीं और नहीं कहा जाता है। क्या यह जीवन चक्र के बारे में कुछ याद आ रही है? नहीं देखा गया DidAppear को एक बार बुलाया जाने की गारंटी है (इसलिए इसे चाबियाँ सही पंजीकृत करनी चाहिए?)

+2

यह एक सुरक्षित तरीका KVO को संभालने के लिए नहीं है। यदि आपका ऐप किसी फोन कॉल द्वारा बाधित है, तो देखें WillDisappear को कॉल नहीं किया जाएगा, लेकिन ऐप रीपंच होने परDidAppear को फिर से कॉल किया जा सकता है। आदर्श संभावनाओं से कई अन्य कम हैं। आपको पर्यवेक्षकों को जोड़ने और निकालने के लिए अधिक विश्वसनीय तरीकों का उपयोग करने पर विचार करना चाहिए (व्यूडिडलोड, डेलोक, आदि) – gurooj

+0

ज्ञान के लिए धन्यवाद। क्या होता है अगर मैं addObserver को दो बार बुलाता हूं? क्या मुझे ऑब्सर्वर को दो बार भी हटाना है? इसके अलावा यह आलेख कहता है कि ViewDidAppear को केवल एक बार बुलाया जाता है: http://stackoverflow.com/questions/11534396/when-is-viewdidappear-called – j2emanue

+0

आपके प्रश्न का उत्तर नहीं दे रहा है, लेकिन आप '@try {[self removeObserver' के साथ त्रुटि से स्वयं को बचा सकते हैं : केप के लिए स्वयं: @ "yourKeyPath"];} @ कैच (एनएसईएक्सप्शन * __unused अपवाद) {} ' – vib

उत्तर

4

कोई गारंटी नहीं है कि viewDidAppear प्रत्येक बार viewWillDisappear से मिलान किया जाएगा। इसका मतलब है कि आपका केवीओ पंजीकरण/अनियंत्रण संभावित रूप से असंतुलित और गैर-निर्धारक होगा। आपको viewDidLoad और dealloc जैसी गारंटीकृत जोड़ी में केवीओ पंजीकरण/अनियंत्रण करना चाहिए।

7

Apple Docs कहता है कि दृश्य केवल दृश्यमान होने पर पर्यवेक्षक को जोड़ने का एक तरीका है। के अनुसार चित्र 1 - मान्य राज्य संक्रमण आप पर्यवेक्षकों को जोड़ने और हटाने के लिए जोड़ी viewWillAppear/viewWillDisppear का उपयोग कर सकते हैं। साथ ही आप init/dealloc जोड़ी का उपयोग कर सकते हैं, लेकिन viewDidLoad/dealloc - दृश्य लोड नहीं किया जा सकता है, लेकिन नियंत्रक को हटाया जा सकता है।

आपका कोड होना चाहिए:

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 

    [self addObserver:self forKeyPath:@"importStuff" options:0 context:NULL]; 
    [self addObserver:self forKeyPath:@"importStuffFailed" options:0 context:NULL]; 
} 

- (void)viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 

    [self removeObserver:self forKeyPath:@"importStuff"]; 
    [self removeObserver:self forKeyPath:@"importStuffFailed"]; 
} 
संबंधित मुद्दे