-
StackOverflow 文档
-
core-data 教程
-
NSFetchedResultsController
-
用于 UITableView 的 NSFetchedResultsController
class ConversationsTableViewController: UITableViewController, NSFetchedResultsControllerDelegate {
private var fetchedResultsController: NSFetchedResultsController<Conversation>!
override func viewDidLoad() {
super.viewDidLoad()
initializeFetchedResultsController()
}
private func initializeFetchedResultsController() {
let request = NSFetchRequest<Conversation>(entityName: "Conversation")
let timeSort = NSSortDescriptor(key: "lastMessageTime", ascending: false)
request.sortDescriptors = [timeSort]
let MOC = AppManagedObjectContext()//It should be main thread MOC
fetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: MOC, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self
do {
try fetchedResultsController.performFetch()
} catch {
print("Failed to initialize FetchedResultsController: \(error)")
}
}
//table view methods
override func numberOfSections(in tableView: UITableView) -> Int {
if let n = fetchedResultsController?.sections!.count {
return n
}
return 0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let sectionInfo = fetchedResultsController.sections![section]
let n = sectionInfo.numberOfObjects
return n
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "identifier", for: indexPath)
//configure cell
return cell
}
//NSFetchedResultsController Delegates
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.beginUpdates()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
switch type {
case .insert:
tableView.insertSections(IndexSet(integer: sectionIndex), with: .fade)
case .delete:
tableView.deleteSections(IndexSet(integer: sectionIndex), with: .fade)
case .move:
break
case .update:
break
}
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
tableView.insertRows(at: [newIndexPath!], with: .fade)
case .delete:
tableView.deleteRows(at: [indexPath!], with: .fade)
case .update:
tableView.reloadRows(at: [indexPath!], with: .none)
case .move:
tableView.deleteRows(at: [indexPath!], with: .fade)
tableView.insertRows(at: [newIndexPath!], with: .fade)
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.endUpdates()
}
}