क्या मैं एआरसी का उपयोग करते समय डीललॉक में शून्य करने के लिए गुण सेट करता हूं?


125

मैं iOS 5 में ऑटोमैटिक रेफरेंस काउंटिंग सीखने की कोशिश कर रहा हूं। अब इस सवाल का पहला भाग आसान होना चाहिए:

  1. क्या यह सही है कि ARC का उपयोग करते समय मुझे अपने प्रेषण में स्पष्ट रिलीज़-प्रॉपर्टी स्टेटमेंट लिखने की आवश्यकता नहीं है? दूसरे शब्दों में, क्या यह सच है कि निम्नलिखित को स्पष्ट सौदे की आवश्यकता नहीं है?

    @interface MyClass : NSObject
    @property (strong, nonatomic) NSObject* myProperty;
    @end
    
    @implementation MyClass
    @synthesize myProperty;
    @end
  2. मेरा अगला और अधिक महत्वपूर्ण प्रश्न एआरसी रिलीज़ नोट्स दस्तावेज़ में संक्रमण की एक पंक्ति से आता है :

    आपको उदाहरण चर नहीं (वास्तव में) जारी करने की आवश्यकता नहीं है, लेकिन आपको एआरसी का उपयोग करके संकलित नहीं किए जाने वाले सिस्टम वर्गों और अन्य कोड पर [स्व सेटलेगेट: एनआईएल] को लागू करने की आवश्यकता हो सकती है।

    यह सवाल भी पैदा करता है: मुझे कैसे पता चलेगा कि कौन से सिस्टम क्लास एआरसी के साथ संकलित नहीं हैं? मुझे अपना खुद का सौदा कब बनाना चाहिए और स्पष्ट रूप से संपत्तियों को बनाए रखना चाहिए? क्या मुझे सभी एनएस और यूआई फ्रेमवर्क वर्गों का उपयोग करना चाहिए जो संपत्तियों में उपयोग किए गए हैं, जिनमें स्पष्ट सौदा करने की आवश्यकता है?

मैनुअल रेफ़रेंस ट्रैकिंग का उपयोग करते समय किसी संपत्ति के बैकिंग आइवर को जारी करने की प्रथाओं पर एसओ और अन्य जगहों पर जानकारी का खजाना है, लेकिन एआरसी का उपयोग करते समय इस बारे में अपेक्षाकृत कम।

जवाबों:


197

संक्षिप्त उत्तर : नहीं, आपको deallocएआरसी के तहत संपत्तियों को बाहर निकालने की आवश्यकता नहीं है ।

लंबे उत्तर : आपको deallocमैनुअल मेमोरी प्रबंधन में भी कभी भी संपत्तियों को बाहर नहीं निकालना चाहिए ।

MRR में, आपको अपने ivars को जारी करना चाहिए । संपत्तियों को बाहर करने का मतलब है कि कॉल करने वाले लोग, जो कोड को लागू कर सकते हैं जिसे यह स्पर्श नहीं करना चाहिए dealloc(जैसे यदि आपकी कक्षा, या उपवर्ग, सेटर को ओवरराइड करता है)। इसी तरह यह KVO सूचनाओं को ट्रिगर कर सकता है। इसके बजाय आइवर को जारी करना इन अवांछित व्यवहारों से बचा जाता है।

एआरसी में, सिस्टम स्वचालित रूप से आपके लिए कोई भी आईवीआर जारी करता है, इसलिए यदि आप ऐसा कर रहे हैं तो आपको लागू करने की आवश्यकता नहीं है dealloc। हालाँकि, यदि आपके पास कोई भी गैर-वस्तु आइवरी है, जिसे विशेष हैंडलिंग की आवश्यकता है (जैसे कि आवंटित बफ़र्स जो आपको चाहिए free()) तो आपको अभी भी उन लोगों से निपटना होगाdealloc

इसके अलावा, यदि आपने खुद को किसी भी वस्तु के प्रतिनिधि के रूप में सेट किया है, तो आपको उस रिश्ते को अन-सेट करना चाहिए dealloc(यह कॉलिंग के बारे में थोड़ा सा है [obj setDelegate:nil])। एआरसी के साथ संकलित नहीं की गई कक्षाओं पर ऐसा करने के बारे में नोट कमजोर गुणों की ओर इशारा है। यदि वर्ग स्पष्ट delegateरूप से अपनी संपत्ति को चिह्नित करता है weakतो आपको ऐसा करने की आवश्यकता नहीं है, क्योंकि कमजोर गुणों की प्रकृति का मतलब है कि यह आपके लिए शून्य हो जाएगा। हालाँकि यदि संपत्ति को चिह्नित किया जाता है assignतो आपको इसे अपने घर से बाहर कर देना चाहिए dealloc, अन्यथा कक्षा एक झूलने वाले सूचक के साथ छोड़ दी जाती है और अगर वह अपने प्रतिनिधि को संदेश देने की कोशिश करती है तो दुर्घटना की संभावना होगी। ध्यान दें कि यह केवल गैर-अनुरक्षित संबंधों पर लागू होता है, जैसे कि प्रतिनिधि।


2
यह समझ में आता है! हालांकि मैं आपसे यह पूछता हूं: मेरे पास एक सामान्य परिदृश्य यह है कि मेरे पास एक MyController : UIViewControllerवर्ग है जो एक UIView बनाता है और उसका मालिक है और अपने आप को देखने का प्रतिनिधि भी निर्धारित करता है। यह उस दृश्य का एकमात्र रिटेनिंग स्वामी है। जब कंट्रोलर डीललॉक्ड हो जाता है, तो व्यू को भी डीललोकेड होना चाहिए। क्या यह तब मायने रखता है जब प्रतिनिधि सूचक झूल रहा हो?
एमफ

4
@emfurry: यह शायद नहीं है, क्योंकि जब तक आपका व्यू कंट्रोलर मर जाता है तब तक व्यू खुद पदानुक्रम में नहीं होना चाहिए और कुछ भी नहीं करना चाहिए, लेकिन यह धारणा बनाने के लिए सबसे अच्छा नहीं है। क्या होगा यदि दृश्य असिंक्रोनस रूप से शेड्यूल किए गए कार्य को बाद में किया जा सकता है, और दृश्य अपने आप ही अपने व्यू कंट्रोलर को थोड़े समय के लिए समाप्त कर देता है (जैसे कि एसिंक्रोनस कार्य अस्थायी रूप से दृश्य बनाए रखने के कारण)? यह सबसे अच्छा है कि प्रतिनिधि को सुरक्षित रखें। और वास्तव में, यदि प्रश्न में दृश्य एक है UIWebView, तो डॉक्स स्पष्ट रूप से बताता है कि आपको प्रतिनिधि को शून्य करने की आवश्यकता है।
लिली बॉलर

3
@zeiteisen: नहीं unsafe_unretained, एक assignसंपत्ति के बराबर है और एमआरआर के तहत प्रतिनिधि संबंधों के लिए सामान्य व्यवहार है, और इन्हें पूरा करने की आवश्यकता है।
लिली बॉलार्ड

4
मैं एमआरसी के साथ डीललोक में बसने का उपयोग नहीं करने के बारे में बयान से सहमत नहीं हूं। Apple इसकी अनुशंसा नहीं करता है, लेकिन वे इसे अपने कोड में भी करते हैं। आप सेटर का उपयोग न करके वास्तव में नई समस्याएं पैदा कर सकते हैं। इसे लेकर कई बड़ी चर्चाएं हैं। जो अशुद्ध है वह सेटर को सही ढंग से लिख रहा है (यदि आप इसे शून्य मान पास करते हैं तो इसे सही ढंग से व्यवहार करना चाहिए) और कभी-कभी डील्लोकेशन का क्रम देखें।
सुल्तान

7
@ सुल्तान: डीललोक में बसने वालों का उपयोग करना या न करना कीड़े की एक बड़ी इच्छा है, लेकिन मेरी स्थिति मूल रूप से उबलती है: आप डीललॉक में जितना संभव हो उतना कम कोड कॉल करना चाहते हैं । सेटर्स में साइड-इफेक्ट्स को शामिल करने की प्रवृत्ति होती है, या तो उपवर्गों में ओवरराइड करके, या केवीओ या अन्य तंत्रों के माध्यम से। डीललोक में साइड-इफेक्ट्स को प्लेग की तरह विशेष रूप से टाला जाना चाहिए। यदि आप संभवतः डीललोक से एक विधि कॉल निकाल सकते हैं, तो आपको ऐसा करना चाहिए। यह नीचे सरलीकृत किया गया है: डीललॉक में बसने वालों को मत बुलाओ।
लिली बॉलार्ड

2

बस उल्टा जवाब देना है ...

संक्षिप्त उत्तर : नहीं, आपको deallocएआरसी के तहत ऑटो-सिंथेसाइज्ड गुणों को बाहर निकालने की जरूरत नहीं है । और आपको उन लोगों के लिए सेटर का उपयोग नहीं करना है init

लंबे उत्तर : आपको एआरसी के तहत कस्टम-संश्लेषित गुणों को बाहर निकालना चाहिएdealloc । और आपको उन लोगों के लिए सेटर का उपयोग करना चाहिए init

बिंदु यह है कि आपके कस्टम-सिंथेसाइज्ड गुण न्यूलीफिकेशन के बारे में सुरक्षित और सममित होना चाहिए।

टाइमर के लिए एक संभावित सेटर:

-(void)setTimer:(NSTimer *)timer
{
    if (timer == _timer)
        return;

    [timer retain];
    [_timer invalidate];
    [_timer release];
    _timer = timer;
    [_timer fire];
}

स्क्रॉलव्यू, टेबलव्यू, वेबव्यू, टेक्स्टफील्ड, ... के लिए एक संभावित सेटर:

-(void)setScrollView:(UIScrollView *)scrollView
{
    if (scrollView == _scrollView)
        return;

    [scrollView retain];
    [_scrollView setDelegate:nil];
    [_scrollView release];
    _scrollView = scrollView;
    [_scrollView setDelegate:self];
}

KVO संपत्ति के लिए एक संभावित सेटर:

-(void)setButton:(UIButton *)button
{
    if (button == _button)
        return;

    [button retain];
    [_button removeObserver:self forKeyPath:@"tintColor"];
    [_button release];
    _button = button;
    [_button addObserver:self forKeyPath:@"tintColor" options:(NSKeyValueObservingOptions)0 context:NULL];
}

तो फिर आप के लिए किसी भी कोड नकल करने की जरूरत नहीं है dealloc, didReceiveMemoryWarning, viewDidUnload, ... और अपनी संपत्ति को सुरक्षित रूप से सार्वजनिक किया जा सकता। यदि आप गुणों को खत्म करने के बारे में चिंतित थे dealloc, तो यह समय हो सकता है कि आप फिर से अपने वासियों की जाँच करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.