7

मैं अब कई घंटों के लिए इस समस्या का निवारण कर रहा हूं, अब तक कोई सफलता नहीं है। मैंने यहां SO पर सभी प्रश्न पढ़े हैं जो मेरी समस्या से संबंधित हो सकते हैं।NSFetchedResultsController का प्रतिनिधि भविष्यवाणी के बाद आग नहीं आता है

मैं दो संस्थाओं (ए, बी) है कि इस तरह एक एक-से-कई-संबंध के माध्यम से एक पेड़ की तरह संरचना में एक दूसरे से जुड़े हुए हैं मिल गया है: एक < --- >> बी

- (NSFetchedResultsController *)fetchedResultsController 
{ 
if (_fetchedResultsController != nil) { 
    return _fetchedResultsController; 
} 

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription entityForName:@"B" inManagedObjectContext:self.managedObjectContext]; 
[fetchRequest setEntity:entity]; 

[fetchRequest setFetchBatchSize:20]; 

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"controlDate" ascending:NO]; 
NSArray *sortDescriptors = @[sortDescriptor]; 
[fetchRequest setSortDescriptors:sortDescriptors]; 

NSMutableArray *subpredicates = [NSMutableArray array]; 
NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"isRelatedTo = %@", selectedObjectOfA]; 
[subpredicates addObject:predicate1]; 
NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"syncStatus != %d", ObjectDeleted]; 
[subpredicates addObject:predicate2]; 

NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subpredicates]; 
[fetchRequest setPredicate:predicate]; 

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil]; 
aFetchedResultsController.delegate = self; 
self.fetchedResultsController = aFetchedResultsController; 

NSError *error = nil; 
if (![self.fetchedResultsController performFetch:&error]) { 
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
    abort(); 
} 

return _fetchedResultsController; 
} 

सब कुछ जोड़ने के लिए ठीक काम करता है, को हटाने:

एक UITableViewController एक NSFetchedResultsController द्वारा समर्थित इकाई बी की सभी वस्तुओं है कि इकाई ए के एक चयनित वस्तु से संबंधित हैं मुझे लगता है कि के लिए विधेय उपयोग कर रहा हूँ दिखाने के लिए नहीं है और वस्तुओं को संपादित करना। तालिका तदनुसार अद्यतन हो जाती है। मेरी कक्षा NSFetchedResultsControllerDelegate के अनुरूप है और प्रतिनिधि विधियां बॉयलरप्लेट हैं।

लेकिन मैं चाहता हूं कि उपयोगकर्ता नेविगेशन स्टैक में वापस जाने के बिना "ऊपर"/"डाउन" बटन टैप करके एंटिटी ए की सभी ऑब्जेक्ट्स के माध्यम से चक्र करने में सक्षम हो सकें (जैसे कोई सीधे ईमेल के माध्यम से ईमेल कर सकता है मेल ऐप)। बी के संबंधित ऑब्जेक्ट्स की संख्या ए के चयनित ऑब्जेक्ट को प्रदर्शित करने में भिन्न होती है (किसी के बीच नहीं और 20 कहें)।

और यहाँ समस्या आता है: मेरे इरादे विधेय बदलकर एफआरसी के परिणामों को रिफ्रेश करने के लिए है (नहीं यह संरचना या वाक्य रचना लेकिन केवल 'selectedObjectOfA' का मान और

[self.fetchedResultsController performFetch:&error]; 

सभी बाकी बुला है एफआरसी के द्वारा किया जाना चाहिए

पहला सवाल होगा:। इस दृष्टिकोण सही है

यहाँ परिदृश्यों मैं पहले से ही की कोशिश की है इस प्रकार हैं:?

  • बस का एक नया मान 'selectedObjectOfA' की स्थापना और performFetch बुला (क्योंकि fetchRequest और विधेय अद्यतन नहीं किया जा रहा है मुझे लगता है) हमेशा एक ही परिणाम से पता चलता

  • 'रीसेट करने' एफआरसी के fetchrequest की तरह इस

    NSMutableArray *subprediactes = [NSMutableArray array]; 
    NSPredicate *predicate1 = [NSPredicate predicateWithFormat:@"isRelatedTo = %@", self.selectedObjectOfA]; 
    [subprediactes addObject:predicate1]; 
    NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"syncStatus != %d", ObjectDeleted]; 
    [subprediactes addObject:predicate2]; 
    
    NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:subprediactes]; 
    [self.fetchedResultsController.fetchRequest setPredicate:predicate]; 
    

अद्यतन करता एफआरसी और सही डेटा रिटर्न के रूप में मुझे लगता है लेकिन पंक्तियों की एक गलत संख्या के साथ ऐप्लिकेशन क्रैश

+०१२३५१६४१०
'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (5), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).' 

क्योंकि NSFetchedResultsController प्रतिनिधि विधियों को कॉल नहीं किया जाता है। इस प्रकार तालिका दृश्य में पंक्तियों की संख्या नए परिणामों के अनुकूल नहीं होती है (लौटाई गई वस्तुओं की संख्या त्रुटि संदेश के अनुसार सही है)।

दूसरा प्रश्न तब है: प्रतिनिधि वस्तुएं जोड़ने/हटाने के दौरान प्रतिनिधि क्यों आग लगती है लेकिन भविष्यवाणियों के बाद नहीं (और इसलिए परिणाम) बदल गए हैं?

अग्रिम धन्यवाद।

उत्तर

3

आप लाने का अनुरोध संशोधित करने के बाद

[tableView reloadData]; 

कॉल करनी होगी।एक प्राप्त परिणाम नियंत्रक केवल performFetch के बाद हुए परिवर्तनों को ट्रैक करता है।

आप तालिका दृश्य की एक एनिमेटेड अद्यतन प्राप्त करने के लिए निम्न को आज़मा सकते हैं (लेकिन मैं अभी तक प्रयास नहीं किया है कि, तो मुझे यकीन है कि अगर यह काम करता है नहीं कर रहा हूँ):

  • कॉल [tableView beginUpdates]
  • सभी "पुरानी" पंक्तियों को हटाने के लिए [tableView deleteRowsAtIndexPaths:...] का उपयोग करें।
  • प्राप्त किए गए परिणाम नियंत्रक लाने का अनुरोध अपडेट करें।
  • [fetchedResultsController performFetch:...] पर कॉल करें।
  • सभी "नई" पंक्तियों को सम्मिलित करने के लिए [fetchedResultsController fetchedObjects] की सभी वस्तुओं के लिए [tableView insertRowsAtIndexPaths:...] पर कॉल करें।
  • [tableView endUpdates] पर कॉल करें।
+0

आप सही हैं। मैंने इस समय भी कोशिश की है और यह काम करता है! दुर्भाग्य से इस मामले में '[tableview startUpdates] 'और' [tableView endUpdates] 'के साथ पंक्ति एनीमेशन (पंक्तियां जोड़ना/हटाना) खो गया है। क्या इसे रखने की संभावना है? यदि मैंने आपको भविष्यवाणी सही ढंग से बदल दिया है और एक नया fetch प्रदर्शन करने से एफआरसी के परिवर्तनों की ट्रैकिंग को फिर से शुरू किया गया है जिसका अर्थ है कि कोई 'चिकनी' संक्रमण संभव नहीं है (क्योंकि प्रतिनिधि को बुलाया नहीं जाता है)। क्या आप पुष्टि कर सकते हैं? – Francesco

+0

@FranzBernt: एनिमेटेड टेबल व्यू अपडेट के साथ एफआरसी फ़ेच अनुरोध को बदलने के लिए कोई "अंतर्निर्मित" विधि नहीं है। - मुझे यह पता था कि इसे कैसे प्राप्त किया जाए (अद्यतन उत्तर देखें), लेकिन मुझे यकीन नहीं है कि यह काम करता है या नहीं। –

+0

@FranzBernt: अगर अद्यतन विधि काम करता है तो कृपया मुझे बताएं। (यदि ऐसा नहीं होता है, तो आपको 'reloadData'' का उपयोग करना होगा)। –

4

विधेय परिवर्तन के बाद अपने tableview चेतन करने के लिए:

NSFetchRequest* fetchRequest = self.fetchedResultsController.fetchRequest; 
fetchRequest.predicate = newPredicate; 

NSArray* objectsBefore = self.fetchedResultsController.fetchedObjects; 

[self.fetchedResultsController performFetch:nil]; 

NSArray* objectsAfter = self.fetchedResultsController.fetchedObjects; 


[self.tableView beginUpdates]; 

if (objectsBefore.count > 0) 
{ 
    for (id objectBefore in objectsBefore) 
    { 
     if ([objectsAfter indexOfObject:objectBefore] == NSNotFound) 
     { 
      NSIndexPath* indexPath = [NSIndexPath indexPathForRow:[objectsBefore indexOfObject:objectBefore] inSection:0] ; 

      [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationMiddle]; 
     } 
    } 
} 

if (objectsAfter.count > 0) 
{ 
    for (id objectAfter in objectsAfter) 
    { 
     if ([objectsBefore indexOfObject:objectAfter] == NSNotFound) 
     { 
      NSIndexPath* indexPath = [NSIndexPath indexPathForRow:[objectsAfter indexOfObject:objectAfter] inSection:0]; 

      [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationMiddle]; 
     } 
    } 
} 

[self.tableView endUpdates]; 
+1

मेरे लिए वास्तव में अच्छा काम करता है, धन्यवाद – bitwit

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

  • कोई संबंधित समस्या नहीं^_^