2017-04-25 87 views
1

我有多個核心數據實體,全部同步到服務器。爲了測試我建立了一個功能,將:1。 刪除所有的核心數據實體的 2.調用API來刷新所有數據NSFetchedResultsController無法識別刪除

 // Next delete data in all entities (but not user) 
    for entity in CoreDataStack.sharedInstance.allEntities() { 
     if (entity != "User") { 
      if (DataAccess.deleteExisting(entityName: entity, inMoc: self.operationMOC)) { 
       print("Deleted OK: \(entity)") 
      } else { 
       print("ERROR deleting \(entity)") 
      } 
     } 
    } 

    .... 

    // Save updates 
    self.operationMOC.performAndWait { 
     do { 
      try self.operationMOC.save() 
     } catch { 
      fatalError("ERROR: Failed to save operation moc: \(error)") 
     } 
    } 
    self.mainThreadMOC.performAndWait { 
     do { 
      try self.mainThreadMOC.save() 
     } catch { 
      fatalError("ERROR: Failed to save main moc: \(error)") 
     } 
    } 

的問題是,NSFetchedResultsController控制我的UI似乎不承認刪除,給了一個錯誤當更新

error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (14) must be equal to the number of rows contained in that section before the update (7), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)

我已經分手刷新功能分爲兩個部分的「didChange」委託方法火災,所以我可以看到刪除決不會被識別,因此有太多的UITableView行當更新激發並嘗試tableView.insertRows(at:...)時。 我也曾嘗試對我的主線程直接更新到MOC - 沒有運氣

我也把以觀察員:

NotificationCenter.default.addObserver(self, selector: #selector(MessagesTab.dataChanged), name: NSNotification.Name.NSManagedObjectContextObjectsDidChange, object: self.mainThreadMOC) 

它將觸發完美地刪除和更新,因此核心數據是做什麼的工作。

因此,在我轉儲NSFetchResults控制器並使用通知滾動自己之前,我的問題是否有人知道我在做什麼錯誤? (無論是代碼還是期望值) 過去一天,我一直在爲此付出沉重的代價,所以我會非常感激地收到任何建議。

我NSFetchedResultsControllerDelegate didChange方法:

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { 
    print(">>>> FRC Change Fired") 
    switch type { 
    case .insert: 
     tableView.insertRows(at: [newIndexPath!], with: .automatic) 
    case .delete: 
     tableView.deleteRows(at: [indexPath!], with: .automatic) 
    case .update: 
     let rowMessage = self.fetchedResultsController.object(at: indexPath!) 
     if let cell = self.tableView.cellForRow(at: indexPath!) as? InterestsListCell { 
      cell.configureWithData(rowMessage) 
     } 
    default: 
     print("Was not a update, delete or insert") 
    } 
} 
+0

您需要發佈您的fetchResultsDelegate didChangeObject方法,這是問題所在。 – SeanLintern88

+0

@ SeanLintern88,感謝您的快速響應。委託方法張貼,雖然我不認爲它有很多錯誤 – redPanda

+0

在您的tableView的numberOfItemForSection,你引用FRC.fetchedObjects.count或自存儲數組? – SeanLintern88

回答

1

非常感謝@JonRose 此代碼不會導致FRC火

// Delete all records for the entity 
    func deleteExisting(entityName: String, inMoc moc: NSManagedObjectContext) -> Bool { 
    do { 
     let request = NSFetchRequest<NSFetchRequestResult>(entityName: entityName) 
     let deleteRequest = NSBatchDeleteRequest(fetchRequest: request) 
     try moc.execute(deleteRequest) 
     return true 
    } catch { 
     print("ERROR: deleting existing records - \(entityName)") 
     return false 
    } 
} 

後來我研究這一點,並希望它能夠幫助別人 - 見WWDC 2015 session on Core Data這張幻燈片顯示在:enter image description here 我曾嘗試使用.refreshAll()和.mergeChages,但對我來說簡單似乎是溝渠我的FRC和你se NSManagedObjectContextDidSave通知