2012-04-03 8 views
11

this question में डैनियल एगर्ट के जवाब के अनुसार, जब NSPrivateQueueConcurrencyType साथ यह कुछ भी कि छू लेती है यह या वस्तुओं है कि भीतर performBlock: या performBlockAndWait:क्या NSMainQueueConcurrencyType का उपयोग करते समय कोर डेटा को प्रदर्शनब्लॉक के भीतर पढ़ना आवश्यक है?

यह के हैं NSMainQueueConcurrencyType के लिए एक ही सच है क्या करने के लिए आवश्यक है एक प्रबंधित वस्तु संदर्भ का उपयोग करते हुए? निम्नलिखित कोड मुख्य थ्रेड पर चल रहा कल्पना कीजिए, उदाहरण के लिए एक UIViewController में:

self.moc = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType] autorelease]; 
//moc setup 

__block RHWidget *widget = nil; 

[self.moc performBlockAndWait:^{ 
    widget = [(RHWidget *)[self.moc objectWithID:self.widgetObjectID] retain]; 
}]; 

self.labelView.text = widget.descriptionString; 

[widget release]; 

यह ब्लॉक के बाहर विजेट का उपयोग करने के लिए सुरक्षित है, क्योंकि हम जानते हैं कि हम मुख्य थ्रेड पर कर रहे हैं?

__block NSString *description = nil; 

[self.moc performBlockAndWait:^{ 
    RHWidget *widget = (RHWidget *)[self.moc objectWithID:self.widgetObjectID]; 
    description = [widget.descriptionString copy]; 
}]; 

self.labelView.text = description; 

[description release]; 

चीजों को बदलना है अगर वहाँ निजी क़तार प्रकार की संभवतः एक और NSManagedObjectContext नहीं है, तो, ब्लॉक में काम कर रही है और एक parentContext रूप self.moc में परिवर्तन को धक्का: या यह यह यह करने के लिए आवश्यक है?

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

+0

एक बहुत व्यापक लेख है [यहां] (http://www.cocoanetics.com/2012/07/multi-context-coredata/) जो संदर्भ समरूपता प्रकारों और घोंसले वाले संदर्भों सहित विभिन्न दृष्टिकोणों का वर्णन करता है। –

उत्तर

6

अद्यतन:WWDC 2011 Session 303 (What's New in Core Data on iOS) के अनुसार, NSMainQueueConcurrencyType मुख्य धागे पर सामान्य संदेश भेजने की अनुमति है; किसी भिन्न थ्रेड से संदर्भ के साथ बातचीत करते समय आपको केवल -performBlock: का उपयोग करने की आवश्यकता है। (ऐप्लिकेशन द्वारा बनाया गया (नीचे अपने मूल जवाब का अभी भी प्रासंगिक भागों।)


मैं किसी ऐप्लिकेशन या दो कि "मुख्य" एमओसी बनाने के लिए Xcode के डिफ़ॉल्ट "मास्टर-डिटेल" एप्लिकेशन टेम्पलेट को संशोधित कर दिया है प्रतिनिधियों और दृश्य नियंत्रकों के बीच पारित) मुख्य-कतार-केवल, और माता-पिता एक निजी-कतार संदर्भ के लिए जो मैं पृष्ठभूमि कार्यों के लिए उपयोग करता हूं जैसे वेब फ़ेच से डेटा आयात करना। इस प्रकार, संदर्भ और इसकी वस्तुओं के अधिकांश उपयोग performBlock: में लपेटे बिना होते हैं। (केवल एक बार जब मैं performBlock: का उपयोग करता हूं, तो यूआई को अपडेट करने के लिए बैकग्राउंड-टास्क संदर्भ से परिवर्तन को मुख्य में वापस लेना है।) बस ठीक काम करता है।

+0

यह वही है जो मैं कर रहा हूं; मुझे एक 'एनएसओपरेशन क्यूयू' के साथ एक सिंगलटन मिला है और प्रत्येक ऑपरेशन को पारित किया गया है जो 'NSPrivateQueueConcurrencyType' के साथ एक संदर्भ है। वे ऑपरेशन ऑब्जेक्ट लेते हैं, अपना काम करते हैं, स्थानीय संदर्भ को सहेजते हैं, फिर पैरेंट संदर्भ को सहेजते हैं, सब कुछ 'performBlock:' के भीतर। सब कुछ ठीक काम करता प्रतीत होता है, लेकिन मैं एक अप्रत्याशित दौड़ की स्थिति या स्मृति प्रबंधन गेटचा के बारे में चिंतित हूं। – roland

+0

@roland। मुझे नहीं लगता कि यह एक सुरक्षित तरीका है क्योंकि NSOperationQueue कई धागे का उपयोग कर सकता है (भले ही इसका maxConcurrentOperationCount 1 है)। जब आप अभिभावक/बाल संदर्भ मेकनिज्म का उपयोग कर रहे हैं तो आपके पास कम समेकन समस्याएं होंगी क्योंकि यह हमेशा माता-पिता का संदर्भ है जो स्टोर तक पहुंचती है। – FKDev

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