2011-04-01 11 views
18

मैं एक dispatch_queue जो अपने मालिक की संपत्ति के माध्यम से पहुँचा है उपयोग कर रहा हूँ, इस तरह:जीसीडी प्रेषण कतार संपत्ति को जारी करने का सही तरीका क्या है?

@property (nonatomic, assign) dispatch_queue_t queue; 

नोट assign कीवर्ड। कतार का उपयोग पूरे ऑब्जेक्ट्स लाइफ में किया जाता है और इस प्रकार ऑब्जेक्ट के स्वामित्व में होता है।

-(void)dealloc 
{ 
    dispatch_release(self.queue); 
    self.queue = nil; 
} 

मैं कैसे ठीक से इस रिलीज करते हैं: मैं कतार जब मालिक वस्तु पुनः आवंटित की जाती है जारी? retain/release काम का उपयोग करेंगे?

रिलीज कॉल करते समय कतार पर लंबित/चल रहे सामान होने पर क्या होता है?

उत्तर

19

निम्नलिखित डेवलपर दस्तावेज़ से चोरी हो गया है:

डिस्पैच कतारों और अन्य प्रेषण वस्तुओं संदर्भ बार गणना डेटा प्रकार हैं। जब आप एक धारावाहिक प्रेषण कतार बनाते हैं, तो इसकी प्रारंभिक संदर्भ संख्या 1 है। आप dispatch_retain और dispatch_release को बढ़ाने और घटाने के लिए फ़ंक्शन की आवश्यकता के अनुसार संदर्भ गणना कर सकते हैं। जब एक कतार की संदर्भ संख्या शून्य तक पहुंच जाती है, तो सिस्टम अतुल्यकालिक कतार को हटा देता है।

जब आपके एप्लिकेशन को अब प्रेषण कतार की आवश्यकता नहीं है, तो इसे को dispatch_release फ़ंक्शन के साथ रिलीज़ करना चाहिए। कतार में सबमिट किए गए किसी भी लंबित ब्लॉक उस कतार, का संदर्भ रखते हैं, इसलिए तक सभी लंबित ब्लॉक पूर्ण होने तक कतार को अस्वीकार नहीं किया जाता है।

ध्यान दें: आप को बनाए रखने या रिहाई वैश्विक प्रेषण से किसी भी कतार, समवर्ती प्रेषण कतारों या मुख्य प्रेषण कतार सहित की जरूरत नहीं है। बनाए रखने के लिए कोई प्रयास या रिलीज कतारों को अनदेखा कर दिया जाता है।

तो कहीं भी आप उपयोग करेंगे - उपयोग का उपयोग करें dispatch_retain और कहीं भी आप उपयोग करेंगे - कृपया dispatch_release का उपयोग करें।

डिस्पैच कतार उद्देश्य-सी ऑब्जेक्ट्स के समान सामान्य स्मृति प्रबंधन सम्मेलनों का पालन करती है। और जब तक पंक्तिबद्ध सभी ब्लॉक समाप्त नहीं हो जाते हैं तब तक उन्हें हटा दिया नहीं जाएगा।

यदि आप एक प्रेषण कतार को बंद करने का कोई तरीका चाहते हैं: किसी भी प्रकार के एपीआई के माध्यम से सभी संलग्न ब्लॉक को रद्द करने का कोई तरीका नहीं है, इसलिए उन्हें हमेशा पूरा होने के लिए चलना चाहिए। इस प्रक्रिया को तेज़ करने का एक तरीका है प्रेषण कतार प्रबंधन के वर्ग में एक बूल चर होना: _isValid। जब आप कतार को बंद करना चाहते हैं, तो आप _isValid को NO पर सेट कर सकते हैं। कतार में सबमिट किए गए सभी ब्लॉक को पहले कोई काम करने से पहले _isValid जांचना चाहिए।

एक पक्ष टिप्पणी: यह NSOperationQueue का उपयोग करने के लिए अधिक उपयुक्त हो सकता है। क्रिस हैंनसन के blog post देखें।

+1

निश्चित रूप से यदि आपके पास कक्षा में एक _isValid था, जो dealloc में सेट है, तो ऑब्जेक्ट नष्ट हो जाएगा जिसका मतलब है कि _isValid को सुरक्षित रूप से पढ़ा नहीं जा सकता - इस के आसपास एक तरीका क्या है? – CiscoIPPhone

+1

दरअसल ऐसा लगता है कि dispatch_group_wait कॉलिंग पूरी तरह से इस समस्या से बच जाएगी। – CiscoIPPhone

+1

@CiscolPPhone "ऑब्जेक्ट नष्ट हो जाएगा" - असल में, ब्लॉक वृद्धि के भीतर संपत्ति का उपयोग नहीं कर पाएगा, इसकी रोकथाम गिनती होगी, इसलिए यह ब्लॉक के पूरा होने तक भी बंद रहेगा, यहां तक ​​कि डेलोक के बाद भी? मैं इस से थोड़ा सा रहा हूं इसलिए मैं आम तौर पर ब्लॉक में कमजोर गुणों का संदर्भ देता हूं (ब्लॉक से पहले मैं '__weak MyClass कमजोर स्वयं = स्वयं' बना देता हूं, फिर ब्लॉक में केवल कमजोर स्वयं का उपयोग करें। फिर अगर ब्लॉक डेलोक के बाद निष्पादित करता है यह सिर्फ एक कमजोर कमजोर पड़ता है। प्रॉपर्टी और सुरक्षित रूप से मर जाता है।) – jankins

1

अगर वहाँ सामान लंबित/जबकि रिहाई बुला कतार पर चल रहा है तो क्या होगा?

यह सुरक्षित है। लंबित/चल रही कतार प्रणाली से बरकरार है। कॉलिंग dispatch_release सिर्फ कतार की बरकरार गिनती को प्रभावित करता है। Dispatch_async के मैन पेज या बहुत आगे देखें।

7

इस बारे में एक दिलचस्प बात यह है कि यदि कतार में सबमिट किए गए ब्लॉक कतार (उदा। "स्वयं") का ऑब्जेक्ट संदर्भित करते हैं, तो ऑब्जेक्ट dealloc पर नहीं पहुंच जाएगा जब तक कि कतार में सभी लंबित ब्लॉक पूर्ण नहीं हो जाते हैं।

यहाँ एक परियोजना है कि इस दर्शाता है:

अपनी संपत्ति

https://github.com/joshrl/GDCQueueDeallocTest

2

सेटअप तो जैसे:

@property (readwrite, strong, nonatomic) __attribute__((NSObject)) dispatch_queue_t queue; 

असाइन निहित है और मजबूत एआरसी कह एक के रूप में यह इलाज के लिए कतार में बनी रहेगी NSObject।

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

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