获取结果控制器在controllerDidChangeContent之后重复结果

时间:2016-12-20 21:12:32

标签: ios swift core-data nsfetchedresultscontroller

我有两张桌子:一张有所有员工的清单,另一张有能够提供某项服务的员工清单(即按摩)。

数据模型如下所示:

enter image description here

每个服务都可以有许多员工提供它,每个员工都可以提供许多服务(多对多关系)。 问题是每次我将员工从Employee List拖放到Employee providing this service时,我从最后一个索引开始时得到结果重复,而当我从第一个索引开始时一切正常。

enter image description here

当我再次加载viewController时(即使没有再次启动应用程序),所有数据都会正确显示。 这里代码:
EmployeesAvailableTableViewController.swift我初始化NSFetchedResultsController

func initializeFetchedResultsController() {
     let appDelegate = UIApplication.shared.delegate as! AppDelegate
     let context = appDelegate.managedObjectContext
     let request: NSFetchRequest<Employee>
     request = NSFetchRequest(entityName: "Employee")
     //this predicate show only those employee who don't have the entity `service` yet.
     request.predicate = NSPredicate(format: "SUBQUERY(service, $c, $c.service_id == %@).@count == 0", (service?.service_id!)!)

     let lastNameSort = NSSortDescriptor(key: "lastName", ascending: true)
            request.sortDescriptors = [lastNameSort]

     fetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)

     fetchedResultsController?.delegate = self

      do {
           //I added this as suggested in another question on stackoverflow but nothing has changed
           if (self.fetchedResultsController?.fetchedObjects == nil){

                try fetchedResultsController?.performFetch()

            }
        } catch {
            fatalError("Failed to initialize FetchedResultsController: \(error)")
        }
}

每个单元格都有一个gestureRecognizer,将此方法作为目标:

func didLongPressCell (gr: UILongPressGestureRecognizer) {

       let eventCell:EmployeeCell =  gr.view as! EmployeeCell
       switch gr.state {
          case .began:

            // other code not relevant .....
          case .changed:

            // other code not relevant .....
          case .ended:

            onDragEnded(employeeCell:eventCell)
          default:
                print("Any other action?")
          }
}

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

 func onDragEnded(employeeCell:EmployeeCell){

        mDraggableEmployeeCell?.removeFromSuperview()
        CoreDataManager.sharedInstance.saveEmployeeServiceRelationship(employeeId: (employeeCell.employee?.employeeId)!, service_id: (service?.service_id)!)
        let detailsNC = splitViewController?.viewControllers[1] as! UINavigationController
         let details = detailsNC.topViewController as! PriceListViewController
            // I am also using controllerWillChangeContent in the other tableView
            details.assignedEmployeeTableView.reloadData()

}

CoreDataManager.swift中是我保存关系的地方

func saveEmployeeServiceRelationship(employeeId: Int32, service_id:String){

            let context = getContext()
            var employee:Employee?
            var service:Service?

            let employeeFetchRequest:NSFetchRequest<Employee> = NSFetchRequest(entityName: "Employee")
            employeeFetchRequest.predicate = NSPredicate(format:"employeeId = %d", employeeId )
            let serviceFetchRequest:NSFetchRequest<Service> = NSFetchRequest(entityName: "Service")
            serviceFetchRequest.predicate = NSPredicate(format:"service_id = %@", service_id )
            do {

                let employeeResult = try context.fetch(employeeFetchRequest)
                let serviceResult = try context.fetch(serviceFetchRequest)

                if employeeResult.count > 0 {
                employee = employeeResult[0]
                }
                if serviceResult.count > 0 {
                    service = serviceResult[0]
                }

                //set relationship
                service?.addToEmployee(employee!)
                do {
                try context.save()
                } catch let error {

                    print(error)
                }


            }catch let err {
                print(err)
            }
}

最后这是我在PriceListViewController

中初始化代码的方法
func initializeFetchedResultsController() {
        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context = appDelegate.managedObjectContext
        context.stalenessInterval = 0
        let request: NSFetchRequest<Employee>

        request = NSFetchRequest(entityName: "Employee")
        request.predicate = NSPredicate(format: "ANY service.service_id == %@", (service?.service_id)!)

        let lastNameSort = NSSortDescriptor(key: "lastName", ascending: true)
        request.sortDescriptors = [lastNameSort]


        fetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
        fetchedResultsController?.delegate = self

        do {

            if (self.fetchedResultsController?.fetchedObjects == nil)
            {

                try fetchedResultsController?.performFetch()

            }
        } catch {
            fatalError("Failed to initialize FetchedResultsController: \(error)")
        }

}
   //both this delegates methods get called 

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.assignedEmployeeTableView.reloadData()
}

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
self.assignedEmployeeTableView.reloadData()
}

0 个答案:

没有答案