2016-04-09 70 views
1

我有一個非常基本的NSFetchedResultsController,向用戶顯示數據UITableView,允許用戶添加一個新的實體等等。NSFetchedResultsController沒有看到插入(或更新)

但是,每當我添加了一個新的實體,我的應用程序崩潰(或有時只是警告)以下消息:

CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of sections. The number of sections contained in the table view after the update (3) must be equal to the number of sections contained in the table view before the update (2), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted). with userInfo (null) 

注意,甚至認爲numberOfRows已經從2更新到3,插入/刪除東西仍然說(0 inserted, 0 deleted)。所以我最好的理解是,NSFetchedResultsController沒有注意到變化或什麼。

我對NSFetchedResultsController代碼:

func fetch(frcToFetch: NSFetchedResultsController) { 

    do { 
     try frcToFetch.performFetch() 
    } catch { 
     return 
    } 
} 

func fetchRequest() -> NSFetchRequest { 

    // Initialize Fetch Request 
    let fetchRequest = NSFetchRequest(entityName: "ItemInfo") 

    // Add Sort Descriptors 
    let nameSortDescriptor = NSSortDescriptor(key: "iName", ascending: true) 
    fetchRequest.sortDescriptors = [nameSortDescriptor] 

    return fetchRequest 
} 


func getFRC() -> NSFetchedResultsController { 

    if let context = self.context{ 
     fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: context, sectionNameKeyPath: "iName.stringGroupByFirstInitial", cacheName: nil) 
     fetchedResultsController.delegate = self 
    } 
    return fetchedResultsController 
} 

func controllerWillChangeContent(controller: NSFetchedResultsController) { 
    tableView.beginUpdates() 
} 

func controllerDidChangeContent(controller: NSFetchedResultsController) { 
    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 { 
      let cell = tableView.cellForRowAtIndexPath(indexPath)! as UITableViewCell 
      configureCell(cell, atIndexPath: indexPath) 
     } 
     break; 
    case .Move: 
     if let indexPath = indexPath { 
      tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
     } 

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

override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
    if let sections = fetchedResultsController.sections { 
     return sections.count 
    } 

    return 0 
} 

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    if let sections = fetchedResultsController.sections { 
     let sectionInfo = sections[section] 
     return sectionInfo.numberOfObjects 
    } 

    return 0 
} 

並插入新記錄的代碼是:

let entity: NSEntityDescription.entityForName("ItemInfo", inManagedObjectContext: self.context!)! 

let record = NSManagedObject(entity: entity, insertIntoManagedObjectContext: self.context!) 

record.setValue(name, forKey: "iName") 
record.setValue(self.billingMode.text, forKey: "iBillingMode") 

do { 
      // Save Record 
      try record.managedObjectContext?.save() 
      try self.context!.save() 
      // Dismiss View Controller 
      dismissViewControllerAnimated(true, completion: nil) 

     } catch { 
      let saveError = error as NSError 
      print("\(saveError), \(saveError.userInfo)") 

      // Show Alert View 
      showAlertWithTitle("Unexpected Error", message: "Your data could not be saved. Please try again later.", cancelButtonTitle: "Done") 
     } 

注意,self.context變量是從具有實際或主視圖控制器通過NSFetchedResultsController

+0

請問您是否可以嘗試刪除您的應用並再次運行? – Khuong

+0

嗯,我無法刪除該應用程序,因爲它包含大量數據。我正在進行更新,目前備份功能已中斷。所以刪除不是一個選項。我曾嘗試「清理生成文件夾」並運行,但問題仍然存在。 –

+2

請注意,問題是*段的數量*而不是*行的數量*。你實現了 - (void)控制器:(NSFetchedResultsController *)控制器didChangeSection:(id )sectionInfo'? – pbasdf

回答

0

請注意,問題是段的數量不是段的行數。您需要實施:

(void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo