2012-08-09 15 views
5

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

समस्या यह है कि जब सरणी को बदलने के लिए समय आता है, तो पढ़ना जारी रहता है।

वर्तमान में इस मुद्दे को हर बार यह कुछ पढ़ता है यह इतना एक प्रति से अधिक करता है से बचने के लिए:

[[theArray copy] operation] //operation being indexOfObject:, objectAtIndex: objectsAtIndexes:, etc. 

प्रति वास्तव में महंगा होता जा रहा है, के लिए (उन हर समय कोई जरूरत नहीं है, खासकर जब जब सरणी है उत्परिवर्तित नहीं किया जा रहा है)।

उत्परिवर्तित होने पर इसे एक्सेस करने में देरी करने के लिए सरणी को कैसे लॉक कर सकता हूं? इस मामले में

+0

आप इस सरणी को कक्षा की अपनी संपत्ति के रूप में क्यों नहीं बनाते हैं और घोषणा के दौरान इसे परमाणु बनाते हैं तो संकलक धागे के बीच किसी प्रकार के सिंक्रनाइज़ेशन का ख्याल रखेगा। – kidsid49

उत्तर

9

अपने सभी सरणी को एक धारावाहिक प्रेषण कतार पर एक्सेस करें। इससे किसी भी दो ऑपरेशन एक ही समय में होने से रोकेगा। Concurrency प्रोग्रामिंग गाइड में "Eliminating Lock-based Code" देखें।

यदि आपको आईओएस> = 4.3 की आवश्यकता हो सकती है, तो आप उत्परिवर्ती संचालन के लिए एक समवर्ती कस्टम कतार और dispatch barriers का उपयोग कर सकते हैं। यह पढ़ने के साथ-साथ एक साथ होने की अनुमति देगा, लेकिन जब एक लिखना जरूरी है तो लिखने तक उन्हें तब तक रखा जाएगा जब तक कि लेखन समाप्त नहीं हो जाता। अवरोध के रूप में सबमिट किया गया ब्लॉक अनिवार्य रूप से एक समवर्ती कतार पर क्रमशः निष्पादित करता है - यह तब तक शुरू नहीं होगा जब तक कि पिछले सभी ब्लॉक समाप्त नहीं हो जाते हैं, न ही बाधा ब्लॉक पूर्ण होने तक कोई भी प्रारंभिक ब्लॉक तब तक शुरू होगा। (यह जस्टिन का उल्लेख है कि रीड-राइट लॉक का जीसीडी संस्करण है।) मैं आपको samples of this के लिए अयोग्य माइक ऐश पर निर्देशित करता हूं।

+1

सही ढंग से हो गया, यह समांतर पाठकों और गैर-अवरुद्ध लेखकों के लिए अनुमति देता है। यह निश्चित रूप से आज पसंदीदा समाधान है। –

2

, आप एक पढ़ने/लिखने के लॉक का उपयोग करने पर विचार करेंगे। कोको उन्हें प्रदान नहीं करता है, लेकिन pthread_rwlock_t pthreads इंटरफेस में उपलब्ध है - pthread.h में घोषित किया गया है। ध्यान दें कि यह @synchronized, या यहां तक ​​कि एक सादा लॉक से अधिक कुशल (आपके उपयोग के लिए) होने जा रहा है।

5

सरल दृष्टिकोण @synchronized उपयोग करने के लिए, इस तरह है:

-(void) accessTheArray { 
    MyClass *obj; 
    @synchronized(theArray) { 
     obj = [theArray objectAtIndex:...]; 
    } 
    [obj someMessage]; 
} 

संपादित करें: एआरसी का उपयोग नहीं हैं, तो आप को बनाए रखने के/वस्तु autorelease, अन्यथा यह सरणी से निकाले जा सकते हैं चाहते हो सकता है (और जारी) someMessage से पहले (इस उत्कृष्ट टिप्पणी के लिए omz के लिए धन्यवाद) कहा जाता है।

+0

यह ध्यान दिया जाना चाहिए कि जबकि एक्सकोड एक कीवर्ड के रूप में @ सिंक्रनाइज़ नहीं है, यह अभी भी काम करता है। –

+0

यदि एआरसी का उपयोग नहीं किया जा रहा है, तो हो सकता है कि आप ऑब्जेक्ट को 'ऑटोटाइज' रखना चाहें, अन्यथा इसे 'कुछ संदेश' कहा जाने से पहले सरणी (और जारी) से हटा दिया जा सकता है। – omz

+0

@omz बहुत बहुत धन्यवाद, यह एक बहुत ही महत्वपूर्ण टिप्पणी है! इस तरह की छोटी चीजें मुझे एआरसी के तहत कितनी आसान है, इस बारे में पूर्ण प्रशंसा प्राप्त करने में मदद करती है। – dasblinkenlight

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