在 Swift 中刷新 NSFetchedResultController

Refresh NSFetchedResultController in Swift

如果用户单击某个操作,我想用不同的谓词刷新 NSFetchedResultController Sheet。

代码如下:

lazy var fetchResultController: NSFetchedResultsController = {

    let fetchRequest = NSFetchRequest(entityName: "Debt")
    let filterText:String?
    let ascending:Bool?

    if NSUserDefaults.standardUserDefaults().objectForKey("filterType")?.stringValue == "name" {
        filterText = "name"
        ascending = true
    }
    else
    {
        filterText = "date"
        ascending = true
    }

    let sortDescriptor = NSSortDescriptor(key: filterText, ascending: ascending!)
    fetchRequest.sortDescriptors = [sortDescriptor]

    let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: CoreDataManager.sharedManager.managedObjectContext, sectionNameKeyPath: filterText, cacheName: nil)
    fetchedResultsController.delegate = self

    return fetchedResultsController
}()

@IBAction func didTouchUpInsideFilterButton(sender: UIBarButtonItem) {

    let alertController = UIAlertController(title: "Filter By:", message: "", preferredStyle: .ActionSheet)

    let nameAction = UIAlertAction(title: "Name", style: .Default) { (UIAlertAction) -> Void in
      NSUserDefaults.standardUserDefaults().setObject("name", forKey: "filterType")

        do {
            try self.fetchResultController.performFetch()
        } catch {
            let fetchError = error as NSError
            print("\(fetchError), \(fetchError.userInfo)")
        }
    };

    let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel) { (UIAlertAction) -> Void in

        self.dismissViewControllerAnimated(true, completion: nil)
    };

    alertController.addAction(nameAction)

    alertController.addAction(cancelAction)

    self.presentViewController(alertController, animated: true, completion: nil)
}

在调用 try self.fetchResultController.performFetch() 方法后的 alertAction 完成块中,不会再次调用 fetchResultController 来更新谓词。

请找到解决方案。

fetchResultController 声明之后的代码块用于 属性 初始化,并且只会 运行 一次,第一次使用 属性。这意味着当 didTouchUpInsideFilterButton 被调用时,设置谓词等的代码块将不会 运行(除非对 self.fetchResultController 的引用是第一次使用 fetchResultController,这似乎不太可能)。

当你想更新它时,你需要在初始化程序之外显式地更改 fetchResultController。