2016-04-11 26 views
1

我遇到了NSFetchedResultsController的問題。nsfetchedResultsController - 合併數據時出錯

我有子類FRC

class InboxFetchResultsController: NSFetchedResultsController { 

    override init() { 
     let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate 

     let fetchRequest = NSFetchRequest(entityName: "Compliment") 

     let firstSortDescriptor = NSSortDescriptor(key: "updatedAt", ascending: false) 
     let secondSortDescriptor = NSSortDescriptor(key: "sendedDate", ascending: false) 
     fetchRequest.sortDescriptors = [firstSortDescriptor, secondSortDescriptor] 
     let privateManagedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType) 
     privateManagedObjectContext.parentContext = appDelegate.cdh.managedObjectContext 
     let user = try! privateManagedObjectContext.existingObjectWithID(CoreDataManager.sharedInstance.getLoggedUser().objectID) as! User 

     let predicate = NSPredicate(format: "recievedBelong = %@", user) 

     fetchRequest.predicate = predicate 

     super.init(fetchRequest: fetchRequest, managedObjectContext: privateManagedObjectContext, sectionNameKeyPath: nil, cacheName: nil) 
// 
     NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(contextDidSaveContext(_:)), name: NSManagedObjectContextDidSaveNotification, object: nil) 
    } 


    deinit{ 
     NSNotificationCenter.defaultCenter().removeObserver(self) 
    } 

    func contextDidSaveContext(notification: NSNotification) { 
     let sender = notification.object as! NSManagedObjectContext 
     if sender != managedObjectContext { 
      self.managedObjectContext.performBlock({ [weak self] in 
       DDLogInfo("Core data merging") 
       self!.managedObjectContext.mergeChangesFromContextDidSaveNotification(notification) 
      }) 

     } 
    } 

} 

而且隨着ComplimentsViewController

lazy var fetchedResultsController: NSFetchedResultsController = { 
    let fetchedResultsController = InboxFetchResultsController() 
    fetchedResultsController.delegate = self 
    fetchedResultsController.fetchRequest.predicate = self.receivedPredicate 
    return fetchedResultsController 
}() 

在viewDidLoad中我打電話

func performFetch() { 
    fetchedResultsController.managedObjectContext.performBlock { [weak self] in 
     do { 
      try self!.fetchedResultsController.performFetch() 
     } catch { 
      let fetchError = error as NSError 
      print("\(fetchError), \(fetchError.userInfo)") 
     } 
     dispatch_async(dispatch_get_main_queue(), { 
      self!.tableView.reloadData() 
     }) 
    } 

extension ComplimentsViewController: NSFetchedResultsControllerDelegate { 
    func controllerWillChangeContent(controller: NSFetchedResultsController) { 
     dispatch_async(dispatch_get_main_queue(), { 
      self.tableView.beginUpdates() 
     }) 
    } 

    func controllerDidChangeContent(controller: NSFetchedResultsController) { 
     dispatch_async(dispatch_get_main_queue(), { 
      self.tableView.endUpdates() 
     }) 

    } 
    func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) { 
     switch (type) { 
     case .Insert: 
      if let indexPath = newIndexPath { 
       tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
      } 
      break; 
     case .Delete: 
      if let indexPath = indexPath { 
       tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
      } 
      break; 
     case .Update: 
      if let indexPath = indexPath { 
       tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic) 
      } 
      break; 
     case .Move: 
      if let indexPath = indexPath { 
       tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
      } 

      if let newIndexPath = newIndexPath { 
       tableView.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade) 
      } 
      break; 
     } 
    } 

我正在使用ViewModel編輯不同View Controller中的獲取對象,該ViewModel是在後臺上下文中分配的。 當我保存的背景下,我得到這個錯誤:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (5) 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, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).' 
*** First throw call stack: 

我花時間照顧有關的併發性, 小時檢查的tableView委託方法... ,仍然可以得到這個問題。

+0

爲什麼你要繼承NSFRC?你在你的子類中所做的任何事都需要一個子類。只需創建一個NSFRC實例。不要繼承。 – Fogmeister

回答

0

您使用NSFetchedResultsController所以你不應該叫:

 


    dispatch_async(dispatch_get_main_queue(), { 
     self!.tableView.reloadData() 
    }) 

 

由於所有NSFetchedResultsControllerDelegate方法在這裏更新您的tableView,它會被自動觸發。

而且你不需要在斯威夫特分號,既不break;switch的默認行爲是要打破,除非你明確提到fallthrough