2011-10-10 11 views
15

पर सीमित करने के लिए पर्याप्त है, मुझे लगता है कि मेरे प्रश्न का उत्तर 'नहीं' है, लेकिन मैं अभी भी उलझन में हूं और इसके बारे में अनिश्चित हूं। तो कृपया पुष्टि करें। एकाधिक धागे के साथ कोर डेटा का उपयोग करते समय मैंने सावधान रहना आवश्यक है। NSManagedObjectContext ऑब्जेक्ट्स थ्रेड सीमाओं को पार नहीं करना चाहिए। दोनों धागे और कोर डेटा के साथ एक नौसिखिया होने के नाते, मुझे खुशी से पता चला कि जीसीडी को इनमें से कुछ आसान बनाना चाहिए।एक जीडीडी प्रेषण कतार है जो कोर डेटा संदर्भ को एक थ्रेड

शायद, मैंने सोचा कि मैं कोर डेटा से निपटने के लिए एक समर्पित जीसीडी प्रेषण कतार तैयार करूंगा (या यदि आवश्यक हो, तो प्रत्येक के पास अपने मूल डेटा संदर्भ के साथ एकाधिक प्रेषण पंक्तियां होंगी)। यह आसान होता।

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

मैंने कई संबंधित प्रश्न और उत्तर पढ़े हैं, उदाहरण के लिए Core Data and threads/Grand Central Dispatch, लेकिन मैं कुछ हद तक उलझन में रहता हूं। जीसीडी कतारों का उपयोग करते हुए उस प्रश्न का स्वीकार्य उत्तर यह सुनिश्चित करता है कि प्रत्येक धागे पर एक नया संदर्भ बनाया गया हो, लेकिन ऐसा करने की आवश्यकता को इंगित नहीं करता है। एक और जवाब कहता है, "आप com.yourcompany.appname.dataaccess नामक कतार पर सभी कोरडाटा कार्य निष्पादित कर सकते हैं" ऐसा लगता है कि जब तक कोर डेटा कार्य एक जीसीडी प्रेषण कतार तक ही सीमित है, तो सब ठीक है। शायद यह नहीं है।

उत्तर

19

अद्यतन: जैसा कि @adib एक टिप्पणी में बताता है, क्रमबद्ध प्रबंधित ऑब्जेक्ट संदर्भ पहुंच के लिए दृष्टिकोण आईओएस 9 और मैकोज़ एक्स 10.11 में बदल गया है। NSConfinementConcurrencyType, थ्रेड कैदीकरण रणनीति, अब NSPrivateQueueConcurrencyType और NSMainQueueConcurrencyType के पक्ष में बहिष्कृत है। दूसरे शब्दों में, कोर डेटा ऑब्जेक्ट्स के समवर्ती उपयोग के लिए थ्रेड का उपयोग करना बंद करें और इसके बजाय जीसीडी का उपयोग शुरू करें। आपको एमओसी को कॉन्फ़िगर करने के तरीके के आधार पर मुख्य प्रेषण कतार या एमओसी से जुड़े एक का उपयोग करना चाहिए, न कि अपनी खुद की सृजन की कतार। NSManagedObject के -performBlock: या -performBlockAndWait: विधियों का उपयोग करना आसान है।


लघु जवाब: एक सीरियल प्रेषण कतार का उपयोग करते हुए एक प्रबंधित वस्तु संदर्भ के लिए धारावाहिक पहुँच प्रदान कर सकते हैं, और कहा कि "धागा कारावास" रणनीति लागू करने के लिए भले ही GCD वास्तव में एक से अधिक थ्रेड काम कर सकते हैं एक स्वीकार्य तरीका है।

लंबे समय तक जवाब:

उस सवाल, GCD कतारों का उपयोग करने के स्वीकार किए जाते हैं जवाब, है कि एक नया संदर्भ प्रत्येक थ्रेड पर बनाई गई है सुनिश्चित करता है, लेकिन ऐसा करने की आवश्यकता का कहना है नहीं है ।

बड़ी बात आपको याद करने की जरूरत है कि आप एक ही समय में दो अलग धागे से प्रबंधित वस्तु संदर्भ को संशोधित करने से बचना चाहिए है। यह संदर्भ को असंगत स्थिति में डाल सकता है, और इससे कुछ भी अच्छा नहीं आ सकता है। तो, आपके द्वारा उपयोग की जाने वाली प्रेषण कतार के महत्वपूर्ण है: एक समवर्ती प्रेषण कतार कई कार्यों को एक साथ आगे बढ़ने की अनुमति देगी, और यदि वे दोनों एक ही संदर्भ का उपयोग करते हैं तो आप परेशानी में होंगे। यदि आप एक सीरियल प्रेषण कतार का उपयोग करते हैं, तो दूसरी तरफ, दो या दो से अधिक कार्य विभिन्न धागे पर निष्पादित हो सकते हैं, लेकिन कार्यों को क्रम में निष्पादित किया जाएगा, और एक ही समय में केवल एक ही कार्य चल जाएगा।यह एक ही धागे पर सभी कार्यों को चलाने के समान ही है, कम से कम जहां तक ​​संदर्भ की स्थिरता को बनाए रखा जाता है।

अधिक विस्तृत स्पष्टीकरण के लिए this question और answer देखें।

इस प्रकार कोर डेटा ने हमेशा काम किया है। कोर डेटा प्रोग्रामिंग गाइड के Concurrency with Core Data सेक्शन में सलाह दी जाती है कि यदि आप एकाधिक धागे में एक संदर्भ का उपयोग करने का निर्णय लेते हैं तो आगे बढ़ना है। जब भी आप इसे एक्सेस करते हैं तो संदर्भ को लॉक करने के लिए मुख्य रूप से बहुत सावधान रहने की आवश्यकता के बारे में बात करते हैं। लॉकिंग के सभी बिंदुओं का बिंदु यह सुनिश्चित करना है कि दो या दो से अधिक थ्रेड एक साथ संदर्भ का उपयोग करने की कोशिश न करें। एक धारावाहिक प्रेषण कतार का उपयोग करना एक ही लक्ष्य प्राप्त करता है: क्योंकि कतार में केवल एक ही कार्य निष्पादित होता है, ऐसा कोई मौका नहीं है कि दो या दो से अधिक कार्य एक ही समय में संदर्भ का उपयोग करने का प्रयास करेंगे।

+1

महान जवाब है, लेकिन जुड़ा हुआ सूत्र में, bbum के भ्रम की स्थिति सूचित करते हैं कि एमओसी वस्तु ही पार धागा सीमाओं, भले ही पहुँच धारावाहिक है नहीं कर सकते हैं लगता है। बेन विशेष रूप से यह बताता है, तो हमें क्या करने की उम्मीद है? –

+2

@SedateAlien, अपने उत्तर में, बेन [दस्तावेज़ीकरण] (http://tinyurl.com/6dlg75j) में नोट को इंगित करता है जो कहता है: *** नोट: ** आप थ्रेड, सीरियल ऑपरेशन कतार, या समेकन के लिए प्रेषण कतार। संक्षेप में, यह आलेख इनमें से किसी भी संदर्भ के लिए "थ्रेड" का उपयोग करता है। "* तो, उसके उत्तर के शेष में, या प्रलेखन में, आप * थ्रेड * के लिए * धारावाहिक प्रेषण कतार * को प्रतिस्थापित कर सकते हैं। , आवश्यक बात यह है कि एक ही समय में अलग-अलग चीजों के लिए एक ही संदर्भ का उपयोग करने से बचें। उल्लेख किए गए तीन तंत्रों में से कोई भी इसे प्राप्त करने के लिए उपयोग किया जा सकता है। – Caleb

+0

तो क्या मैं कहा गया है कि एमओसी ने कहा सीरियल कतार पर? यदि मैं एमओसी ऑब्जेक्ट बनाता हूं ऑफ-कतार, लेकिन केवल इसे कतार में उपयोग करें, क्या यह स्वीकार्य है या परेशानी के लिए पूछ रहा है? –

0

AFAIK आप सही हैं; जीसीडी उस धागे के बारे में गारंटी नहीं देता है जिसमें कतार चलती है। कतार में भेजे गए ब्लॉक और फ़ंक्शन कॉल एक समय में एक चलाए जाएंगे, लेकिन यदि कोर डेटा वर्तमान थ्रेड के साथ कुछ करता है, उदा। एक रन लूप स्रोत या पर्यवेक्षक स्थापित करता है, चीजें शायद इरादे के रूप में काम नहीं करेंगे।

हालांकि, मैक ओएस एक्स 10.7 पर, NSManagedObjectContext मुख्य थ्रेड पर चलाने के लिए, एक अलग थ्रेड पर या सेट किया जा सकता, एक निजी कतार में।