2012-02-02 9 views
295

एआरसी के तहत सिंगलटन के साझा इंस्टेंस एक्सेसर में dispatch_once का उपयोग करने का सटीक कारण क्या है?ऐप्पल एआरसी के तहत सिंगलटन पैटर्न को लागू करने के लिए dispatch_once का उपयोग करने की सलाह क्यों देता है?

+ (MyClass *)sharedInstance 
{ 
    // Static local predicate must be initialized to 0 
    static MyClass *sharedInstance = nil; 
    static dispatch_once_t onceToken = 0; 
    dispatch_once(&onceToken, ^{ 
     sharedInstance = [[MyClass alloc] init]; 
     // Do any other initialisation stuff here 
    }); 
    return sharedInstance; 
} 

क्या पृष्ठभूमि में सिंगलटन को असीमित रूप से तुरंत चालू करना बुरा विचार नहीं है? मेरा मतलब है कि क्या होता है यदि मैं उस साझा उदाहरण का अनुरोध करता हूं और तुरंत उस पर भरोसा करता हूं, लेकिन प्रेषण तक मेरी वस्तु बनाने के लिए प्रेषण लेता है? यह तुरंत वापस नहीं आता है? कम से कम ऐसा लगता है कि ग्रैंड सेंट्रल डिस्पैच का पूरा बिंदु है।

तो वे ऐसा क्यों कर रहे हैं?

+0

'नोट: स्थिर और वैश्विक चर शून्य पर डिफ़ॉल्ट हैं। – ikkentim

उत्तर

406

dispatch_once() बिल्कुल तुल्यकालिक है। सभी जीसीडी विधियां असीमित रूप से चीजें नहीं करती हैं (बिंदु में, dispatch_sync() तुल्यकालिक है)। dispatch_once() का उपयोग निम्नलिखित मुहावरा बदल देता है:

+ (MyClass *)sharedInstance { 
    static MyClass *sharedInstance; 
    @synchronized(self) { 
     if (sharedInstance == nil) { 
      sharedInstance = [[MyClass alloc] init]; 
     } 
    } 
    return sharedInstance; 
} 

dispatch_once() इस ओवर की लाभ यह है कि यह तेजी से है। यह भी अर्थात् क्लीनर है, क्योंकि यह आपके साझा किए गए इंस्टेंस के आवंटित करने वाले एकाधिक थ्रेडों से भी आपकी सुरक्षा करता है - यदि वे सभी एक ही सटीक समय पर प्रयास करते हैं। यह दो उदाहरणों को बनाने की अनुमति नहीं देगा। dispatch_once() का पूरा विचार "एक बार और केवल एक बार कुछ करें", जो ठीक है हम क्या कर रहे हैं।

+4

तर्क के लिए मुझे यह ध्यान रखना होगा कि [प्रलेखन] (https://developer.apple.com/library/mac/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html#//apple_ref/c/ func/dispatch_once) यह नहीं कहता कि इसे समकालिक रूप से निष्पादित किया जा रहा है। यह केवल इतना कहता है कि एकाधिक एक साथ आविष्कार क्रमबद्ध किया जाएगा। – expert

+5

आप दावा करते हैं कि यह तेज़ है - कितना तेज़? मेरे पास यह सोचने का कोई कारण नहीं है कि आप सच नहीं कह रहे हैं, लेकिन मैं एक साधारण बेंचमार्क देखना चाहता हूं। –

+29

मैंने अभी एक साधारण बेंचमार्क किया है (आईफोन 5 पर) और ऐसा लगता है कि प्रेषण_सिस @ सिंक्रनाइज़ेड से लगभग 2x तेज है। –

39

क्योंकि यह केवल एक बार चलाएगा। तो यदि आप विभिन्न धागे से दो बार कोशिश करते हैं और इसे एक्सेस करते हैं तो इससे कोई समस्या नहीं होगी।

माइक एश का Care and Feeding of Singletons ब्लॉग पोस्ट में पूरा विवरण है।

सभी जीसीडी ब्लॉक असीमित रूप से नहीं चल रहे हैं।

+11

केविन एक बेहतर जवाब है, लेकिन मैं माइक एश के पोस्ट को लिंक रखने के लिए अपना छोड़ रहा हूं। – Abizern

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

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