15

से निष्पादित कोर डेटा प्रविष्टियों को पूर्ववत करना मैं कुछ कोड पर काम कर रहा हूं जो डेटा आयात करने के लिए NSOperation का उपयोग करता है। मैं चाहता हूं कि उपयोगकर्ता आयात ऑपरेशन के दौरान बनाए गए NSManagedObject उदाहरण पूर्ववत करने में सक्षम हो।मुख्य डेटा

जो मैं कह सकता हूं उससे, मुख्य थ्रेड से किए गए किसी भी ऑपरेशन के लिए NSManagedObjectContext-undoManager का उपयोग करना असंभव है। कोर डाटा प्रोग्रामिंग गाइड पर उपयोग अनुभाग से बन्दिश थ्रेड कन्करेंसी समर्थन करने के लिए, हम इन दो शर्तें:

  1. केवल objectId पारित किया जाना चाहिए प्रबंधित वस्तु संदर्भों के बीच ( अलग धागे पर)
  2. प्रबंधित ऑब्जेक्ट से पहले किसी संदर्भ में सहेजा जाना चाहिए ऑब्जेक्ट आईडी का उपयोग किया जा सकता है।

यह समझ में आता है के बाद से प्रबंधित वस्तुओं सार्वजनिक भंडारण (NSPersistentStore) इससे पहले कि वे साझा किया जा सकता करने के लिए निजी भंडारण (NSManagedObjectContext) में ले जाया जाना चाहिए।

दुर्भाग्यवश, -save: संदेश पूर्ववत स्टैक को हटाने के लिए किसी भी प्रबंधित ऑब्जेक्ट का भी कारण बनता है। मेमोरी मैनेजमेंट का उपयोग करते हुए कोर डाटा एक ही गाइड की धारा से:

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

मैं इस सीमा के आसपास काम करने के लिए कई बातें की कोशिश की है, और सब कुछ अंत में काम मुख्य थ्रेड पर हो रहा के थोक करने के लिए वापस ले जाते हैं (और समुद्र तट गेंदों कताई।) प्राप्त करने के लिए किसी भी सुराग बंद बनाई गई वस्तुओं के साथ काम करने को पूर्ववत मुख्य धागा बहुत सराहना की जाएगी।

-

एक वृद्धि रडार प्रस्तुत किया गया है: rdar://problem/8977725

+0

क्यों न केवल इस ऑपरेशन द्वारा डाले गए सभी प्रबंधित ऑब्जेक्ट आईडी का लॉग रखें? इस तरह यदि उपयोगकर्ता इसे वापस रोल करना चाहता है तो आप ऑब्जेक्ट को फिर से हटा सकते हैं और हटा सकते हैं। यदि आपको उत्परिवर्तन वापस भी रोल करना होगा, तो कुंजी/मूल्य परिवर्तनों का रिकॉर्ड रखना भी मुश्किल नहीं है। पूर्ववत प्रबंधक में जूता-सींग की कोशिश करने से सरल लगता है। – ImHuntingWabbits

+0

उपर्युक्त टिप्पणी के संबंध में, आप फिर से सौंपने का सुझाव कैसे देंगे? – wbyoung

उत्तर

0
नहीं

एक विशेषज्ञ है, लेकिन मुझे लगता है कि आप तो विलय, कार्रवाई करने के लिए एक दूसरी प्रसंग बना है क्या करने की जरूरत करने जा रहे हैं एक साथ दो संदर्भ। आप विलय को पूर्ववत चरण के रूप में प्रबंधित करने में सक्षम होना चाहिए। नोट, यह केवल तभी काम करता है जब आप संचालन के पूरे सेट को एक पूर्ववत चरण के रूप में देखते हैं, जहां तक ​​उपयोगकर्ता का संबंध है।

+0

मैं पहले से ही एक -मेजChangesFromContextDidSaveNotification कर रहा हूं: मुख्य संदर्भ पर संदर्भ संदर्भ में आयात संदर्भ में परिवर्तनों का प्रचार करने के लिए। समस्या यह है कि मर्ज ऑब्जेक्ट ग्राफ़ को उस डेटा के साथ समायोजित करता है जो पहले से ही लगातार स्टोर में है। मुख्य थ्रेड पर NSManagedObjectContext में कोई भी -इनर्टेड ऑब्जेक्ट्स या -अपडेटेड ऑब्जेक्ट्स नहीं हैं जिन्हें लगातार स्टोर में लिखा जाना आवश्यक है। – chockenberry

0

मान लीजिए कि आप पृष्ठभूमि धागे के लिए एक अलग संदर्भ का उपयोग करते हैं, और एक बार यह हो जाने के बाद, [[backgroundContext undoManager] undo] को अग्रभूमि थ्रेड के पूर्ववत स्टैक पर दबाएं? मैंने कभी ऐसा कुछ भी नहीं किया है, लेकिन मेरे सिर के ऊपर से मैं एक कारण के बारे में नहीं सोच सकता कि इसे काम नहीं करना चाहिए।

+0

"[[backgroundContext undoManager] पूर्ववत] अग्रभूमि धागे के पूर्ववत स्टैक पर आपका क्या मतलब है? जो मैं पूर्ववत स्टैक की सामग्री को बता सकता हूं उससे निजी हैं ... – chockenberry

+0

[[[अग्रभूमि कॉन्टेक्स्ट अंडोमेनगर] तैयार करेंथिथोकेशन लक्ष्य: [backgroundContext undoManager]] पूर्ववत करें]; (असल में, आपको पृष्ठभूमिकेंटेक्स्ट को भी सहेजने की आवश्यकता होगी ...) –

+0

इसके साथ कुछ समस्याएं हैं: पृष्ठभूमिकॉन्टेक्स्ट एक अल्पकालिक धागा है जो अग्रभूमि कॉन्टेक्स्ट लंबी अवधि में लक्षित नहीं कर पाएगा। साथ ही, जैसे ही पृष्ठभूमि कॉन्टेक्स्ट -वेव भेजता है: अग्रभूमि कार्य के साथ काम करने के लिए पूर्ववत स्टैक पर कुछ भी नहीं है। – chockenberry

0

एक विकल्प आपके आयात धागे को लगातार बनाने के लिए हो सकता है। यहां तक ​​कि जब धागा आयात करना समाप्त हो जाता है, यह एक निष्क्रिय पाश स्थिति में जाता है। इस तरह आपके थ्रेडेड प्रबंधित ऑब्जेक्ट कॉन्टेक्स्ट उचित थ्रेड में बने रहे हैं। फिर जब उपयोगकर्ता परिवर्तन को पूर्ववत करना चाहता है, तो अंडरमेनर का उपयोग करने के लिए थ्रेड को एक संदेश भेजें।

+0

यहां समस्या यह है कि प्रबंधित ऑब्जेक्ट संदर्भ एक दूसरे के सम्मिलित ऑब्जेक्ट्स के बारे में नहीं जानते हैं जब तक -व: ऐसा होता है। किस बिंदु पर पूर्ववत ढेर टूट गया है ... – chockenberry

2

यह उत्तर शायद पीछे और पीछे का होगा। अगर मैं सही ढंग से इस मुद्दे को समझता हूं, तो आप एक आयात कर रहे हैं लेकिन जब आयात किया जाता है तो आप चाहते हैं कि उपयोगकर्ता आयात से बचाए गए को चुनने में सक्षम हो?

यदि यह सही नहीं है, तो कृपया मेरी मान्यताओं को ठीक करें और मैं इस उत्तर को अपडेट कर दूंगा।

यदि यह सही है तो आप क्या कर सकते है:

  1. एक सरणी में

    NSEntityDescription *myEntity = ... //Entity from your context 
    [[NSManagedObject alloc] initWithEntity:myEntity 
         insertIntoManagedObjectContext:nil]; 
    
  2. स्टोर इन संस्थाओं के लिए अपनी पृष्ठभूमि ऑब्जेक्ट निर्माण बदलें।
  3. इकाइयों को आवश्यकतानुसार अपने मुख्य धागे पर वापस पास करें।
  4. किसी भी ऑब्जेक्ट पर रिलीज़ करें जिसे आप
  5. [myMainContext insertObject:managedObject] पर कॉल करना चाहते हैं, जिसे आप रखना चाहते हैं।
  6. NSManagedObjectContext पर एक सेव करें।

के बाद से इन संस्थाओं एक NSManagedObjectContext का हिस्सा नहीं हैं फिर भी वे केवल स्मृति में मौजूद हैं और सुरक्षित हैं क्योंकि वे अभी तक एक NSManagedObjectContext करने के लिए नीचे जुड़ा नहीं है, थ्रेड किया जाना चाहिए।

यह निश्चित रूप से सैद्धांतिक है और परीक्षण की आवश्यकता होगी। हालांकि यह आपके लक्ष्य को पूरा करना चाहिए।

+0

है [initWithEntity: इकाई insertIntoManagedObjectContext: nil] सही और काम करने वाला कोड? क्या आप उन अस्थायी वस्तुओं के लिए इन-मेमोरी एमओसी नहीं बनाना चाहते हैं? –

+0

यह आवश्यक नहीं है। 'एनएसईएनटीटी डिस्क्रिप्शन' को हल करने के लिए आपको एक एमओसी की आवश्यकता है लेकिन एमओ को एमओसी के साथ अस्तित्व में रहने की जरूरत नहीं है। इसे सहेजने के लिए केवल एमओसी से जुड़ा होना चाहिए। –

+0

जानना कूल है। जानकारी के लिए धन्यवाद। –

0

यह अविश्वसनीय रूप से संभावना है कि आप इस पर विचार किया है और आप की संभावना केवल मौजूदा undoManager का उपयोग कर एक समाधान के लिए देख रहे हैं, लेकिन सिर्फ मामले में:

आप ऑब्जेक्ट सम्मिलित कर रहे हैं और मौजूदा अपडेट नहीं हो के बाद से, आप कर उनके पास एक लेनदेन आईडी के साथ टैग करने की शक्ति है क्योंकि प्रत्येक बैच आयात किया जाता है, उन्हें पूर्ववत के मामले में पृष्ठभूमि थ्रेड में हटाया जाता है। टैग के लिए एक सरल वृद्धि NSNumber पर्याप्त है।

सुरुचिपूर्ण, लेकिन व्यावहारिक।

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