0

我正在使用NSFetchedResultsController使用來自coredata實體的數據跟蹤和加載UITableView兩節(基於可用true或false)。 Coredata實體由azure syncTable拉方法填充。我從VC中的ViewDidLoad()方法調用fetchedDataController?.performFetch()。 數據分爲兩部分 - 第1部分可用爲false,第2部分 - 在實體數據中可用。從SyncTable拉的核心數據對象更新,而不是調用NSFeatchedResults委託方法

這裏是NSFRC初始化代碼片段:

lazy var fetchedDataController: NSFetchedResultsController<Product>? = { 

     let req = NSFetchRequest<NSFetchRequestResult>(entityName: "Product") 

     req.sortDescriptors = [NSSortDescriptor(key: "available", ascending: true),  NSSortDescriptor(key: "createdAt", ascending: false)] 
     guard let dbContext = self.appDelegate?.managedObjectContext else { return nil } 

     let controller = NSFetchedResultsController(fetchRequest: req, managedObjectContext: dbContext, sectionNameKeyPath: "available", cacheName: nil) as? NSFetchedResultsController<Product> 

     controller?.delegate = self 
     return controller 
    }() 

問題: 1.即使存在實體行的數據FRC委託方法更新不會自動解僱。就像我在後端將其從true更改爲false並執行了SyncTable.pull,我可以看到coredata表已更新爲最新數據(我打開了.sql文件並能夠看到數據)

  1. 爲了克服每次執行pull操作時執行提取的解決方法,在這種情況下,當我向下滾動到第2部分時,應用程序崩潰時出現索引錯誤,這意味着它沒有正確更新表格部分和行。

委託方法實現:

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 

    self.tableView.beginUpdates() 
} 

    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
     self.tableView.endUpdates() 
    } 

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) { 
     let sectionIndexSet = IndexSet(integer: sectionIndex) 
     switch type { 
      case .insert: 
       self.tableView.insertSections(sectionIndexSet, with: .fade) 
      case .update: 
       self.tableView.reloadSections(sectionIndexSet, with: .fade) 
      case .delete: 
       self.tableView.deleteSections(sectionIndexSet, with: .fade) 
      default: break 
     } 
    } 


    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { 
     switch type { 
      case .insert: 
       if let newIndex = newIndexPath { 
        self.tableView.insertRows(at: [newIndex], with: .fade) 
       } 
      case .update: 
       if let index = indexPath { 
        self.tableView.reloadRows(at: [index], with: .fade) 
       } 
      case .move: 
       if let index = indexPath { 
        self.tableView.deleteRows(at: [index], with: .fade) 
        if let newIndex = newIndexPath { 
         self.tableView.insertRows(at: [newIndex], with: .fade) 
        } 
       } 
      case .delete: 
       if let index = indexPath { 
        self.tableView.deleteRows(at: [index], with: .fade) 
       } 
      default: break 
     } 
    } 

我堅持到這個任何幫助表示讚賞。

+0

可能不相關,但'fetchedDataController'應該是不可選的:'懶VAR fetchedDataController:NSFetchedResultsController = {''讓REQ = NSFetchRequest (entityName:「Product」)''並刪除可選類型cast'as? NSFetchedResultsController '。你**做**創建一個獨特的類型的控制器,你**做**知道它永遠不會'無'。 – vadian

+0

@vadian類型轉換的FRC到實體類型是必需的,否則編譯器抱怨.. – AjDev

+0

如果你不指定申報行類型:'NSFetchedResultsController '而不是'NSFetchedResultsController ' – vadian

回答

0

添加觀察員managedobjectcontext保存解決了這個問題:

NotificationCenter.default.addObserver(自我,選擇:#selector(refreshContent),名稱:NSNotification.Name.NSManagedObjectContextDidSave,對象:無)

func refreshContent(notif:Notification) { self。 fetchedDataController .managedObjectContext.mergeChanges?(fromContextDidSave:notifn)

}

0

fetchedResultsController監視特定的上下文 - 而不是sql文件。如果你在應用程序中有多個上下文,那麼從一個更改可能不會合併到另一個。所以即使sql文件更新了,上下文也不會。在創建上下文時,請確保設置viewContextautomaticallyMergesChangesFromParent = true。

+0

試過這個沒有奏效,但我能解決我的問題,在這裏添加答案。 – AjDev