8

मेरे पास UITableView है (कस्टम सेल के साथ, यदि यह मायने रखता है) NSFetchedResultsController पर लगा हुआ है। मेरा ऐप पुश अधिसूचनाओं का भी उपयोग करता है। जब कोई रिमोट अधिसूचना आती है, तो मैं अपने (कोर) डेटा मॉडल को दो चरणों में अपडेट करता हूं:NSFetchedResultsController लगातार देरी; तत्काल कार्य

1) शीर्षक प्राप्त करें (कुछ कस्टम डेटा के साथ) और इसे एक नए कोर डेटा Entity के रूप में संग्रहीत करें। यहां मैं NSManagedObjectContext save() पर कॉल करता हूं। NSFetchedResultsController डालने को उठाता है और didChangeObjectNSFetchedResultsChangeType = NSFetchedResultsChangeInsert के साथ इसकी प्रतिनिधि विधि didChangeObject निकालता है। टेबलव्यू तुरंत अद्यतन किया जाता है। (एक नई पंक्ति डाली गई है)

2) NSURLSession के माध्यम से सेल से संबंधित अधिक सामग्री डाउनलोड करें इसे ऊपर Entity में डालें और फिर save() method पर कॉल करें। NSFetchedResultsController फिर से अपडेट को उठाता है और didChangeObjectNSFetchedResultsChangeType = NSFetchedResultsChangeUpdate के साथ इसकी प्रतिनिधि विधि didChangeObject को चलाता है। यह वह जगह है जहां मैं अपना configureCell विधि कहता हूं। TableView अपडेट किया गया है लेकिन लगभग 10 सेकंड की लगातार देरी के साथ।

दोनों चरणों (डाउनलोड-संदर्भ सेव-अपडेट टेबलव्यू) पर दिखाए जाने वाले डेटा को पहले से ही कोर डेटा द्वारा जारी रखा गया है। (के लिए मेरी configureCell.. विधि के अंदर जैसे, मैं जानता हूँ कि मैं nil या उस तरह के किसी भी सेल लेबल की स्थापना नहीं कर रहा हूँ

मेरे NSFetchedResultsController प्रतिनिधि तरीके:।

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { 
[self.mainTableView beginUpdates]; 
} 

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { 
[self.mainTableView endUpdates]; 
} 


- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { 
UITableView *tableView = self.mainTableView; 

switch(type) { 

    case NSFetchedResultsChangeInsert: 
     [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     break; 

    case NSFetchedResultsChangeUpdate: 
     [self configureCell:(MessageTableViewCell *)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; 
    } 
} 

अन्य चीजें हैं जो मैं case NSFetchedResultsChangeUpdate:

अंदर की कोशिश की है
  1. संदर्भ save
  2. reloadRowsAtIndexPaths कहा जाता है से पहले के बजाय फोन करने processPendingChanges बुला की कोशिश की configureCell सीधे
  3. अद्यतन लपेटकर की कोशिश की .. beginUpdates और endUpdates
  4. [tableView reloadData]
  5. numberOfRowsInSection 0 नहीं है (हालांकि मैं पहले से ही एक जोड़ी है जो काम करना चाहिए) के अंदर तरीकों!
  6. NSFetchedResultsController प्रतिनिधि पद्धति केवल मुख्य धागे पर चलती हैं।

संक्षेप में, सभी (?) उचित प्रतिनिधि तरीकों को सही तरीके से बुलाया जा रहा है। फिर भी मैं सेल को अद्यतन करते समय लगातार ~ 10 सेक देरी देखता हूं। हालांकि, सम्मिलन लगभग तत्काल होता है। कोई विचार?

+0

नेटवर्क ऑपरेशन पूर्ण होने के बाद आप तालिका को अपडेट करते समय कोड नहीं दिखाते हैं, लेकिन मुझे लगता है कि आप मुख्य कतार पर अपडेट प्रेषित नहीं कर रहे हैं। – Paulw11

+0

ठीक है, अगर अपडेट को "प्रेषण" करके, आप 'save' को कॉल करना चाहते हैं, तो नहीं, मैं 'NSURL सत्र' प्रतिनिधि विधि से 'save' को कॉल कर रहा हूं' URLSession: downloadTask: didFinishDownloadingToURL: 'जो मुख्य थ्रेड पर नहीं है अगर मै गलत नहीं हूँ? –

+0

तो आप अपने द्वारा बनाए गए पृष्ठभूमि थ्रेड संदर्भ का उपयोग कर रहे हैं और परिवर्तन को सहेज रहे हैं? – Wain

उत्तर

4

@ पॉलव 11 की टिप्पणी dispatch_async... ने मुझे सही दिशा में बंद कर दिया। समस्या इस तथ्य में निहित है कि मैं एक ही ManagedObjectContext ऑब्जेक्ट का उपयोग दो अलग-अलग धागे में कर रहा हूं, भले ही वे एक साथ एक साथ नहीं पहुंचते हैं। जैसे ही मैंने मुख्य कतार पर save कॉल (जो पृष्ठभूमि धागे पर थे) भेज दिया (इसे dispatch_async(dispatch_get_main_queue,^{ UIUpdate code here }); के अंदर लपेटकर), देरी गायब हो गई। एक संभावित स्पष्टीकरण यह होगा कि पृष्ठभूमि धागे पर save पर कॉल करने से पृष्ठभूमि थ्रेड पर प्रतिनिधि विधियों को कॉल किया जा सकता है।

वैसे भी, समाधान पर वापस - एकाधिक धागे के बीच समान ManagedObjectContext ऑब्जेक्ट साझा न करें। Use parent/child context relationships यदि आप एक से अधिक धागे में कोर डेट अपडेट कर रहे हैं।NSFetchedResultsController भी इस पैटर्न के साथ अच्छी तरह से खेलता है।

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