केवीओ और एआरसी कैसे हटाने के लिए


87

एआरसी के तहत आप किसी ऑब्जर्वर को किसी ऑब्जेक्ट से कैसे हटा सकते हैं ? क्या हम सिर्फ पर्यवेक्षक जोड़ते हैं और इसे हटाने के बारे में भूल जाते हैं? यदि हम अब मेमोरी को मैन्युअल रूप से प्रबंधित नहीं करते हैं तो हम अवलोकन करने से कहाँ इस्तीफा देते हैं?

उदाहरण के लिए, एक दृश्य नियंत्रक पर:

[self.view addObserver:self
            forKeyPath:@"self.frame"
               options:NSKeyValueObservingOptionNew 
               context:nil];

पहले, मैं removeObserver:दृश्य नियंत्रक की deallocविधि में कॉल करूंगा ।


4
ध्यान दें कि यह KVO .frame के लिए एक बहुत बुरा विचार है। जैसा कि StackOverflow पर Apple इंजीनियरों ने लिखा है, UIKit की फ्रेम प्रॉपर्टी KVO के अनुरूप नहीं है। जब यह काम करता है, तो यह केवल शुद्ध संयोग से होता है।
स्टेपिपेट

2
क्या आपका की-पाथ @"frame"इसके बजाय नहीं होना चाहिए @"self.frame"?
Besi

जवाबों:


126

आप अभी भी -deallocएआरसी के तहत कार्यान्वयन कर सकते हैं , जो प्रमुख मूल्यों के अवलोकन को हटाने के लिए उपयुक्त स्थान प्रतीत होता है। आप बस [super dealloc]इस पद्धति से किसी भी अधिक कॉल नहीं करते हैं ।

यदि आप -releaseपहले ओवरराइड कर रहे थे , तो आप चीजों को गलत तरीके से कर रहे थे।


1
क्या तुम इसके बारे में निश्चित हो? मैं clang.llvm.org/docs/… , खंड 7.1.2 से उद्धृत करता हूं । सौदा: "तर्क: भले ही एआरसी उदाहरण चर स्वचालित रूप से नष्ट कर देता है, लेकिन अभी भी एक वैध तरीके को लिखने के लिए वैध कारण हैं, जैसे गैर-अनुरक्षित संसाधनों को मुक्त करना। इस तरह की विधि में [सुपर डीलॉक] कॉल करने में विफल होना लगभग हमेशा एक बग है।"
बजे एलिस वैन लोइज

@ElisevanLooij हाँ यह सच है। यदि आप इस वर्ग से निकलते हैं, तो यह स्पष्ट प्रतीत होता है कि आपको कॉल करना होगा [super dealloc]। आपके लिए और कौन ऐसा करना चाहिए।
ब्योर्न लैंडमेसर

@ElisevanLooij उफ़, ठीक है, पहले जाँच करनी चाहिए थी। इसे [super dealloc]डीलॉक विधि में कॉल करने की अनुमति नहीं है । पता नहीं कैसे यह तब काम करेगा जब उल्लिखित वर्ग को उपवर्ग में रखा जाए। शायद इसके finalizeबजाय उपयोग करने की सलाह दी जाती है (जहां आप कॉल करते हैं [super finalize])
ब्योर्न लैंडमेसर

17
@ElisevanLooij - वे जिस बिंदु को बनाने की कोशिश कर रहे थे वह मैनुअल मेमोरी प्रबंधन मामले के संबंध में है। चूँकि [super dealloc]उस विधि में अंतिम बार कॉल न करना मैनुअल मेमोरी प्रबंधन के तहत हमेशा एक बग होता है, इसलिए कंपाइलर इसे आपके लिए संभालता है, यही कारण है कि अब आप -deallocसीधे कॉल नहीं कर सकते । -deallocएआरसी के तहत एक विधि में आपके द्वारा डाली गई एकमात्र चीजें हैं किसी भी गैर-ऑब्जेक्ट संसाधन जो आपको मुक्त करने की आवश्यकता है, या पर्यवेक्षकों को हटाने जैसे कार्यों को साफ करने की आवश्यकता है। जो शब्द वे उपयोग करते हैं वह थोड़ा मैला है, लेकिन इसका मतलब यह है कि वे।
ब्रैड लार्सन

7
@ BjörnMilcke - जैसा कि मैं एलिस के जवाब पर टिप्पणी करता हूं, -finalizeइसका उपयोग कचरा संग्रह के तहत किया जाता है, जहां -deallocइसे कभी नहीं बुलाया जाता है, लेकिन -deallocएआरसी के तहत इस कोड को रखने के लिए यह पूरी तरह से स्वीकार्य है । [super dealloc]आपके लिए स्वचालित रूप से कॉल किया जाता है, यही वजह है कि एआरसी के तहत इसे कॉल करना एक त्रुटि है।
ब्रैड लार्सन

1

मैं इसे इस कोड के साथ करता हूं

- (void)dealloc
{
@try{
    [self.uAvatarImage removeObserver:self forKeyPath:@"image" context:nil];
} @catch(id anException) {
    //do nothing, obviously it wasn't attached because an exception was thrown
}
}    

2
एक्सेप्शन हैंडलिंग की बात क्या है dealloc? इसके बारे में कुछ भी करने के लिए बहुत देर हो चुकी है।
अबिज़र्न

डीललोक में उदाहरण चर पर पर्यवेक्षकों को हटाने का क्या मतलब है? इस uAvatarImage को किसी भी पर्यवेक्षक के साथ जल्द ही निपटाया जाएगा, जिसने इसके प्रमुख पथों की सदस्यता ली है।
शौमिकिन

1
@shoumikhin मैं एआरसी का उपयोग कर रहा हूं और मुझे डीलॉक विधि में पर्यवेक्षक को निकालना था। मेरे पास वही प्रश्न है जो आपके पास है। हालाँकि, जब मैंने कक्षा के कई उदाहरणों को चलाया तो अंततः मुझे exc_bad_address त्रुटि मिली। ऐसा करने से समस्या हल हो गई। इसके अलावा, यहां से जवाब stackoverflow.com/questions/32490808/… ने मुझे इस मुद्दे को खोजने में मदद की।
19106 में mac10688

-2

स्टैक ओवरफ्लो पर कहीं और, क्रिस हैनसन इस उद्देश्य के लिए अंतिम विधि का उपयोग करने और एक अलग अमान्य विधि को लागू करने की सलाह देता है ताकि मालिक वस्तुओं को बता सकें कि वे किए गए हैं। अतीत में मैंने हैनसन के समाधानों को अच्छी तरह सोचा-समझा है, इसलिए मैं उसके साथ जा रहा हूं।


13
ध्यान दें कि वह वहां कचरा संग्रहण की बात कर रहा था, न कि एआरसी (उसका जवाब 2008 में लिखा गया था)। कचरा संग्रह के तहत, -deallocकभी नहीं कहा जाता है। एआरसी में, यह है। यह में KVO पर्यवेक्षकों को दूर करने के पूरी तरह से स्वीकार्य है -dealloc:, क्रिस लैटनर (कौन जानता है कि वह क्या बारे में बात कर रहा है) यहाँ तक एप्पल के डेवलपर मंचों इंगित करता है के रूप में devforums.apple.com/message/475850
ब्रैड लार्सन

3
धन्यवाद ब्रैड, यह सब काम करने के लिए। अंतिम रूप देने के लिए नहीं, हां डील करने के लिए लेकिन बिना [सुपर डीलॉक] के। सरल वास्तव में, एक बार जब आप इसे जानते हैं। अरे, @drunknbass, स्वीकार करो उस आदमी का जवाब!
Elise van Looij
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.