0

問題NSFetchedResultsController是我提取數據,它填充UITableViewcacheName設置爲nil。稍後,當我更改NSFetchedResultsControllerpredicate並將其稱爲perfromFetch時,它將不會刷新UITableView,但NSFetchedResultsController中的數據已更新。還有一件事,NSFetchedResultsControllerDelegate方法也沒有調用。NSfetchedResultsController更改不反映到UI

在此先感謝。

編輯:添加的代碼

NSFetchedResultsControllerDelegate

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

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { 

    UITableView *tableView = self.tableView; 

    switch(type) { 

     case NSFetchedResultsChangeUpdate: 
      [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; 
      [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

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

     case NSFetchedResultsChangeDelete: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeMove: 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 
    } 
} 

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type { 

    switch(type) { 

     case NSFetchedResultsChangeInsert: 
      [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeDelete: 
      [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade]; 
      break; 

     case NSFetchedResultsChangeMove: 
     case NSFetchedResultsChangeUpdate: 
      break; 
    } 
} 

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

NSFetchedResultsController

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

    NSManagedObjectContext *context = [GmailDBService sharedService].managedObjectContext; 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Thread"]; 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"historyId" ascending:NO]; 
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"SUBQUERY(messages, $m, ANY $m.labels.identifier == %@)[email protected] > 0", self.label.identifier]; 
    fetchRequest.sortDescriptors = @[sortDescriptor]; 
    fetchRequest.fetchBatchSize = 20; 

    _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil]; 
    _fetchedResultsController.delegate = self; 
    [_fetchedResultsController performFetch:nil]; 

    return _fetchedResultsController; 
} 

謂語刷新

- (IBAction)unwindToThreadsController:(UIStoryboardSegue *)segue 
{ 
    self.fetchedResultsController.fetchRequest.predicate = [NSPredicate predicateWithFormat:@"identifier == %@", @"15f1919682399cc9"]; 
    [self.fetchedResultsController performFetch:nil]; 
} 
+0

你是否將NSFetchedResultsController委託設置爲自己? –

+0

是的,我做了,並在稍後交叉檢查。代表完好無損,與以前一樣。 –

+0

你可以發佈一些代碼,很難假設你的項目中可能發生了什麼。發佈代碼的相關部分將有助於我們爲您提供更好的解決方案 –

回答

0

fetchedResultsCo ntroller並不昂貴。你不應該無心創建並根據需要銷燬它們。當您需要更改謂詞時放棄當前的fetchedResultsController並創建一個新的。在這樣做之後,不要忘記重新加載tableView。

更改不會觸發fetchedResultsController,因爲您正在監視線程,但謂詞基於消息。所以當消息被改變時,它不會觸發fetchedResultsController中的更改。控制器只監視對一個實體的更改,並且不希望其他實體發生更改來影響它。你可以通過幾種方法解決這個問題:1)設置你的fetchedResultsController來查看消息並按線程分組,然後只顯示每一部分(即線程)作爲一行。 2)每次你改變一條消息也改變它的線程(message.thread.threadId = message.thread.threadId將被視爲一個改變,就fetchedResultsController而言)。

此外,fetchBatchSize不受fetchedResultsController的重視,因此爲了清晰起見您應該將其刪除。