Swift3 CoreData - fetchResultsController
Posted
技术标签:
【中文标题】Swift3 CoreData - fetchResultsController【英文标题】: 【发布时间】:2017-06-25 17:42:27 【问题描述】:我收到此错误: ItinerariesCodeChallenge[2594:1022206] *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“NSFetchedResultsController 的一个实例需要一个带有排序描述符的获取请求这是我的代码。真的很感谢你的帮助,我已经尝试了好几天了......
import UIKit
import CoreData
class MainVC: UIViewController, UITableViewDelegate, UITableViewDataSource, NSFetchedResultsControllerDelegate
// outlets & properties:
@IBOutlet weak var tableView: UITableView!
var controller: NSFetchedResultsController<Itineraries>!
override func viewDidLoad()
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
override func viewWillAppear(_ animated: Bool)
attemptFetch()
tableView.reloadData()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CellContent
configureCell(cell: cell, indexPath: indexPath as NSIndexPath)
return cell
func configureCell(cell: CellContent, indexPath: NSIndexPath)
let itinerary = controller.object(at: indexPath as IndexPath)
cell.configureCell(itineraries: itinerary)
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
if let objs = controller.fetchedObjects, objs.count > 0
let itinerary = objs[indexPath.row]
performSegue(withIdentifier: "toDetailsVC", sender: itinerary)
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
if segue.identifier == "toDetailsVC"
if let destination = segue.destination as? DetailVC
if let itinerary = sender as? Itineraries
destination.itineraryToEdit = itinerary
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
if let sections = controller.sections
let sectionInfo = sections[section]
return sectionInfo.numberOfObjects
return 0
func numberOfSections(in tableView: UITableView) -> Int
if let sections = controller.sections
return sections.count
return 0
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return 140
func attemptFetch()
let fetchRequest: NSFetchRequest<Itineraries> = Itineraries.fetchRequest()
let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
controller.delegate = self
self.controller = controller
do
try controller.performFetch()
catch
let error = error as NSError
print("\(error)")
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>)
tableView.beginUpdates()
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>)
tableView.endUpdates()
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?)
switch(type)
case.insert:
if let indexPath = newIndexPath
tableView.insertRows(at: [indexPath], with: .fade)
break
case.delete:
if let indexPath = indexPath
tableView.deleteRows(at: [indexPath], with: .fade)
break
case.update:
if let indexPath = indexPath
let cell = tableView.cellForRow(at: indexPath) as! CellContent
configureCell(cell: cell, indexPath: indexPath as NSIndexPath)
break
case.move:
if let indexPath = indexPath
tableView.deleteRows(at: [indexPath], with: .fade)
if let indexPath = newIndexPath
tableView.insertRows(at: [indexPath], with: .fade)
break
【问题讨论】:
【参考方案1】:请仔细阅读错误信息,它准确地说明了问题所在
NSFetchedResultsController 的实例需要带有排序描述符的获取请求。
添加至少一个排序描述符:
let fetchRequest: NSFetchRequest<Itineraries> = Itineraries.fetchRequest()
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "...")]
let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
旁注,与问题无关:删除所有类型转换as NSIndexPath
,它们是多余的。
【讨论】:
以上是关于Swift3 CoreData - fetchResultsController的主要内容,如果未能解决你的问题,请参考以下文章
Swift3 CoreData - fetchResultsController
如何使用 Swift3 访问 CoreData 中的数据索引