5

मुझे एक पृष्ठभूमि स्टोर थ्रेड ने इसके संदर्भ को सहेजने के बाद लगातार स्टोर में किए गए परिवर्तनों को प्रतिबिंबित नहीं करते हुए एक NSManagedObject से परेशानी हो रही है।NSManagedObject पृष्ठभूमि थ्रेड के बाद परिवर्तनों को प्रतिबिंबित नहीं कर रहा है NSManagedObjectContextDidSaveNotification

सेटअप

एक साधारण परीक्षण आवेदन में मैं एक एकल खिड़की है कि मेरे कोर डेटा लगातार दुकान में वस्तुओं की सभी सूचीबद्ध करता है, एक खोज और परिणामों को फ़िल्टर करने के लिए बॉक्स को पाठ फ़ील्ड नाम दिखाने के लिए चयनित आइटम का और नाम बदलने की अनुमति दें।

 
ArrayController --> AppDelegate --> ManagedObjectContext 
TableView Col 1 --> ArrayController --> values --> arrangedObjects.widgetName 
TableView Col 2 --> ArrayController --> values --> arrangedObjects.uid 

SearchField --> ArrayController --> predicate --> filterPredicate 

TextField --> ArrayController --> value --> selection.widgetName 

मैं भी एक बटन शुरू होता है कि एक पृष्ठभूमि (NSOperation) एक वेब सर्वर से डेटा के लाने के लिए है:

बाइंडिंग इस प्रकार हैं।

प्रक्रिया

उपयोगकर्ता ताज़ा करें बटन क्लिक करता है, एक NSOperation लात मारी है बंद हो जाता है और कि विजेट पकड़ लेता एसिंक्रोनस तरीके, स्थानीय विगेट्स के लिए चेक को हटाने के लिए कि प्रतिक्रिया में नहीं हैं प्रतिसाद पार्स, जोड़ने के लिए नए विजेट जो स्थानीय रूप से और मौजूदा स्थानीय विजेट्स को संग्रहीत नहीं किए जाते हैं जिन्हें सर्वर के रूप में पुनर्प्राप्त डेटा के साथ अद्यतन किया जाना चाहिए।

एक बार संसाधन समाप्त होने के, मुख्य संदर्भ का उपयोग करते हुए अधिसूचित किया गया है:

[mainContext performSelectorOnMainThread: 
     @selector(mergeChangesFromContextDidSaveNotification:) 
           withObject:notification 
          waitUntilDone:YES]; 

मैं पता चलता है कि परिवर्तन ठीक और मुख्य नियंत्रक अधिसूचित कर ली माध्यम से चला गया के परीक्षण के लिए मुख्य नियंत्रक में एक पर्यवेक्षक की है।

समस्या

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

उदाहरण के लिए

, तीन विगेट्स निम्नलिखित और पहचान पत्र दिए गए:

 
Test Name 1 | ID 123 
Renamed 2 | ID 234 
Test Name 3 | ID 345 

जब मैं पर ताज़ा:

 
Test Name 1 | ID 123 
Test Name 2 | ID 234 
Test Name 3 | ID 345 

अगर मैं Renamed 2 करने के लिए Test Name 2 के यूआई में नाम बदल मैं निम्नलिखित है पृष्ठभूमि, मैं चाहता हूं कि सूची सर्वर के राज्य को प्रतिबिंबित करे, यानी वापस जाएं:

 
Test Name 1 | ID 123 
Test Name 2 | ID 234 
Test Name 3 | ID 345 

इसके बजाय यह बनी हुई है:

 
Test Name 1 | ID 123 
Renamed 2 | ID 234 
Test Name 3 | ID 345 

मैं जानता हूँ कि लगातार दुकान अद्यतन किया गया था क्योंकि अगर मैं XCode और फिर से लॉन्च से एप्लिकेशन को मारने के लिए, वांछित जानकारी प्रदर्शित होता है। यदि मैं सामान्य रूप से ऐप छोड़ देता हूं, तो बदले गए मूल्य को स्टोर पर स्टोर पर लिखा जाता है और फिर से खोलने का नाम बदलकर मूल्य दिखाता है।

मैं

क्या कोशिश की है मैं जानता हूँ कि संदेश मुख्य संदर्भ के रूप पृष्ठभूमि भेजा जा रहा है और मुझे पता है डेटा स्टोर करने के लिए एक समान होती जा रही है। इसलिए, मेरा मानना ​​है कि मुख्य संदर्भ विलय नहीं कर रहा है क्योंकि मैं इसकी अपेक्षा करता हूं, या मुझे किसी भी तरह से सरणी नियंत्रक को लगातार स्टोर से लाने और इसके संदर्भ को त्यागने की आवश्यकता है।

  • मैं दुकान की सूचना पर processPendingChanges: की कोशिश की है बचाने के लिए, लेकिन मुझे लगता है मैं तो बस दुकान में Renamed 2 लिख रहा हूँ।
  • मैं सरणी नियंत्रक पर एक rearrangeObjects कर की कोशिश की है, लेकिन जैसा कि एरे नियंत्रक मुख्य संदर्भ के साथ काम कर रहा है मुझे लगता है यह मैं सरणी नियंत्रक पर एक fetch:nil कर की कोशिश की है कुछ भी नहीं
  • कर रही है से लाए जाने क्या करने के लिए लगातार स्टोर, लेकिन एक बार फिर मुझे संदेह है कि मुख्य संदर्भ Renamed 2 के मान को ओवरराइट कर रहा है क्योंकि यह अभी तक सहेजा नहीं गया है।
  • मैं प्रति एप्पल डॉक्स के रूप में सरणी नियंत्रक पर fetchWithRequest:nil merge:NO error:&error की कोशिश की है, लेकिन अभी भी यह प्रदर्शित मान

मैं क्या सोचते जरूरतों होने की अपने डेटा को बचाने के लिए एरे नियंत्रक के लिए है बदलने के लिए प्रतीत नहीं होता बैकग्राउंड स्टोर डेटा लिखने से पहले लगातार स्टोर पर जाएं ताकि सरणी नियंत्रक पर एक लाए जाने से डेटा मेरी अपेक्षाओं के अनुसार सटीक हो सके। और यदि यह वास्तव में मामला है, तो मैं यह करने के लिए सरणी नियंत्रक को कैसे बताऊंगा, या सरणी नियंत्रक को केवल बाइंडिंग के माध्यम से परिवर्तनों के बारे में पता होगा यदि मुख्य प्रबंधित ऑब्जेक्ट कॉन्टेक्स्ट किसी भी तरह से सहेजा गया था?

मैं लगातार स्टोर से एक fetch करके, उस डेटा को सरणी में डालकर और setContent: को सर नियंत्रक पर कर कर समाधान को हैक कर सकता हूं और फिर लगातार स्टोर सहेजने पर इसे दोहरा सकता हूं, लेकिन यह बस गलत लगता है, नहीं उस समय के मुद्दे का उल्लेख करने के लिए सरणी नियंत्रक की चयनित स्थिति को ट्रैक करना है (और संभवतः किसी भी उप-सरणी चयन जो उस प्राथमिक चयन के परिणामस्वरूप हो रहा है)।

क्या मैं आधार से बाहर हूं? मैं स्पष्ट रूप से यहाँ कुछ याद कर रहा हूँ।

ज्ञान या सलाह के किसी भी शब्द की बहुत सराहना की जाएगी।

उत्तर

3

आह निराशा की शक्ति दृढ़ संकल्प के साथ मिलकर। मुझे यकीन नहीं है कि यह जरूरी है कि यह सर्वोत्तम या अनुशंसित दृष्टिकोण है, लेकिन यह निश्चित रूप से मेरी ज़रूरतों को पूरा करता है।

मेरा लक्ष्य किसी भी गैर-लगातार परिवर्तनों को पृष्ठभूमि अद्यतन सहेजने से पहले जारी रखना था, या पृष्ठभूमि अद्यतन से पहले त्याग दिया जाना था। दोनों मेरी दुनिया में एक ही उद्देश्य की सेवा करते हैं (सर्वर डेटा हमेशा सही होता है)।

बाहर कर देता है मैं बस मेरी NSOperation में एक पर्यवेक्षक को जोड़ने के लिए की जरूरत:

NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; 
[nc addObserver:self 
     selector:@selector(prepareMerge:) 
      name:NSManagedObjectContextWillSaveNotification object:ctx]; 

कौन सा आपरेशन में एक विधि कॉल:

-(void)prepareMerge:(NSNotification *)notification { 

    [[NSNotificationCenter defaultCenter] 
     postNotificationOnMainThreadName:@"SaveNow" 
            object:nil]; 
} 

अधिसूचना मुख्य थ्रेड को भेजा जाता है (के सौजन्य से NSNotificationCenter पर एक श्रेणी cocoanetics.com पर पोस्ट की गई) जो मुख्य धागे पर प्रासंगिक कक्षा में सुनाई जाती है:

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(saveNow:) 
              name:@"SaveNow" 
              object:nil]; 
,210

और निश्चित रूप से विधि है कि वास्तव में परिवर्तन करता है:

-(void)saveNow:(NSNotification *)aNote { 

    [[self managedObjectContext] rollback]; 
} 

एरे नियंत्रक और किसी भी अन्य UI घटक है कि मूल्यों को अद्यतन किया है रोलबैक सही से पहले बचाने के लिए प्रतिबद्ध हो जाता है। बचाता है और पुराने स्थानीय मूल्यों को सभी नए मानों से बदल दिया जाता है।

काम किया।

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