मुझे क्या करना कोशिश कर रहा हूँ से टकराने के बिना: यूआई ठंड के बिनाबचत NSManagedObjectContext मुख्य थ्रेड
- एक वेब एपीआई के साथ पृष्ठभूमि सिंक प्रदर्शन करते हैं। मैं MagicalRecord का उपयोग कर रहा हूं लेकिन यह वास्तव में इसके लिए विशिष्ट नहीं है।
- यकीन है कि मैं संदर्भों का उपयोग कर रहा & सही ढंग से
ऐसी क्या मेरे सवाल का सच है: मेरी समझ सही है? इसके अलावा अंत में कुछ सवाल।
तो, MagicalRecord द्वारा उपलब्ध कराए गए संदर्भों हैं:
- PrivateQueueConcurrencyType जो दुकान है, जो एक धीमी प्रक्रिया
- की MR_defaultContext है करने के लिए डेटा लागू करने के लिए प्रयोग किया जाता है की MR_rootSavingContext MainQueueConcurrencyType
- और पृष्ठभूमि के लिए आप एक संदर्भ जेनरेशन के साथ काम करना चाहते हैं
- MR_saveToPersistentStoreWithCompletion: टेड MR_context द्वारा(), जो अब MR_defaultContext के बच्चा है और की है PrivateQueueConcurrencyType
, एक अतुल्यकालिक तरह से बचाने के लिए, हम दो विकल्प हैं() जो MR_rootSavingContext तक सभी तरह से सहेज लेगा और डिस्क
- MR_saveOnl पर सहेजें ySelfWithCompletion() जो केवल मूल संदर्भ तक ही बचाएगा (i? e। MR_defaultContext
वहां से एक संदर्भ MR_context के साथ बनाया) के लिए, मैंने सोचा कि मैं निम्नलिखित (इसे 1) यूआई ठंड के बिना # प्रयास कॉल कर सकता है:
let context = NSManagedObjectContext.MR_context()
for i in 1...1_000 {
let user = User.MR_createInContext(context) as User
context.MR_saveOnlySelfWithCompletion(nil)
}
// I would normally call MR_saveOnlySelfWithCompletion here, but calling it inside the loop makes any UI block easier to spot
लेकिन, मेरी धारणा थी गलत। मैं looked into MR_saveOnlySelfWithCompletion और देखा कि यह
[self performBlock:saveBlock];
एसिंक्रोनस रूप से रिसीवर की कतार पर दिए गए ब्लॉक करता है पर निर्भर करता है।
तो मैं थोड़ा परेशान था, क्योंकि मैं उम्मीद करता हूं कि यह यूआई को अवरुद्ध न करें।
तो मैं करने की कोशिश की (के इसे कहते प्रयास # जाने 2)
let context = NSManagedObjectContext.MR_context()
for i in 1...1_000 {
let user = User.MR_createInContext(context) as User
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {() -> Void in
context.MR_saveOnlySelfWithCompletion(nil)
}
}
और यह काम करता है, लेकिन यह सही नहीं लगता है।या performBlockAndWait: विधि यदि आपका कोड पहले से ही उस पर क्रियान्वित नहीं है
तब मैं जब एक कतार संघ के साथ बनाई गई एक संदर्भ को संदेश भेजने के लिए, आप performBlock का उपयोग करना चाहिए release notes of iOS 5.0
में कुछ पाया कतार ( मुख्य कतार प्रकार के लिए) या एक प्रदर्शन के दायरे के भीतर ... आमंत्रण (निजी कतार प्रकार के लिए)। उन विधियों को पारित ब्लॉक के भीतर, आप स्वतंत्र रूप से NSManagedObjectContext के तरीकों का उपयोग कर सकते हैं।
तो, मुझे लगता है कि यह सोचते हैं हूँ:
- प्रयास # 1 यूआई जमा क्योंकि मैं वास्तव में मुख्य पंक्ति से और एक performBlock
- प्रयास # के दायरे के भीतर नहीं यह फोन कर रहा हूँ 2 काम करता है, लेकिन मैं अपने आप ही पृष्ठभूमि धागा अभी तक एक और धागा बना रहा हूं संदर्भ पहले से ही है, जबकि
तो of course क्या मुझे क्या करना चाहिए उपयोग saveWithBlock है:
MagicalRecord.saveWithBlock { (localContext) -> Void in
for i in 1...1_000 {
User.MR_createInContext(context)
}
}
यह ऑपरेशन on a direct child of MR_rootSavingContext करता है जो PrivateQueueConcurrencyType का है। rootContextChanged के लिए धन्यवाद, MR_rootSavingContext तक जाने वाला कोई भी परिवर्तन MR_defaultContext पर उपलब्ध होगा।
तो ऐसा लगता है कि:
- MR_defaultContext सही संदर्भ है जब यह इस तरह के एक के रूप में प्रदर्शित डेटा
- संपादन अधिमानतः एक MR_context (MR_defaultContext के बच्चे) में किया जाता
- लंबी चलने वाली कार्यों की बात आती है सर्वर सिंक को प्राथमिक रूप से saveWithBlock
क्या यह अभी भी नहीं मिलता है यह है कि MR_save [...] के साथ काम करने के लिए कैसे करें()। मैं इसे MR_context पर उपयोग करूंगा लेकिन चूंकि यह मेरे परीक्षण मामलों में मुख्य धागे को अवरुद्ध करता है, इसलिए मुझे यह नहीं दिखता कि यह कब प्रासंगिक हो जाता है (या जो मैंने याद किया ...)।
अपने समय के लिए धन्यवाद :)
धन्यवाद, दिलचस्प जवाब। "हर वस्तु निर्माण के लिए बचाने की कोई ज़रूरत नहीं है।" - दरअसल, मैंने यह सुनिश्चित करने के लिए किया था कि मुख्य धागे पर कोई अवरोधन करना आसान होगा, मुझे इसका उल्लेख करना चाहिए था। MR_saveOnlySelfWithCompletion कॉल निष्पादन आंतरिक रूप से अवरोधित करें, यही कारण है कि मुझे समझ में नहीं आता कि यूआई अवरुद्ध क्यों है। – Nycen
प्रदर्शनब्लॉक गारंटी नहीं देता है कि इसे पृष्ठभूमि थ्रेड पर निष्पादित किया जाएगा लेकिन धागे पर संदर्भ बाध्य है। यदि यह मुख्य संदर्भ है तो यह सामान्य रूप से अवरुद्ध होगा। असल में, लगता है कि मुख्य धागे पर, प्रदर्शन ब्लॉक के बाहर या अंदर एक संदर्भ विधि को कॉल करना वही है! तो सुनिश्चित करें कि आपका संदर्भ मुख्य नहीं है। (मैंने अपना जवाब संपादित किया) –
जबकि आपका उत्तर शानदार है, मैं इस बात से असहमत हूं कि "हर ऑब्जेक्ट सृजन के लिए सहेजने की कोई ज़रूरत नहीं है।" ज्यादातर मामलों में यह सच हो सकता है, लेकिन यदि उस विशेष संदर्भ में आप संपादन कर रहे हैं तो अक्सर अन्य संदर्भों में परिवर्तनों को धक्का देना आवश्यक है, इसकी आवश्यकता हो सकती है। साथ ही साथ, जिन्हें आप पूर्ववत नहीं कर सकते हैं :) – Tim