由于未捕获的异常,我的 Xcode 应用在尝试实施 NSFetchedResultsController 后崩溃 'NSInvalidArgumentException'
My Xcode App crashes after trying to implement NSFetchedResultsController due to uncaught exception 'NSInvalidArgumentException'
我最近问了一个关于如何为我的 CoreData 实体实现删除功能的问题。 (这里:How do I delete CoreData entries in a tableview that uses a persistentcontainer?)我被告知我应该使用 NSFetchResultsController,所以我开始着手处理它。我以为我做对了我的代码现在在 运行.
后立即崩溃
我试过使用教程来实现 FetchedResultsController。我很确定我已正确执行所有步骤以在我的应用程序中实施,但它仍然崩溃。我的尝试在下面提供。我的原始代码在上面的段落中。
ViewController.swift
import UIKit
import CoreData
class ViewController: UITableViewController {
//var alarmItems: [NSManagedObject] = []
let cellId = "cellId"
private let persistentContainer = NSPersistentContainer(name: "AlarmItems")
fileprivate lazy var fetchedResultsController: NSFetchedResultsController<AlarmItems> = {
//create fetch request
let fetchRequest: NSFetchRequest<AlarmItems> = AlarmItems.fetchRequest()
//configure fetch request
//fetchRequest.sortDescriptors = [NSSortDescriptor(key: )]
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.persistentContainer.viewContext, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self as? NSFetchedResultsControllerDelegate
return fetchedResultsController
}()
override func viewDidLoad() {
super.viewDidLoad()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
//let managedContext = appDelegate.persistentContainer.viewContext
//let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "AlarmItems")
do {
//alarmItems = try managedContext.fetch(fetchRequest)
try fetchedResultsController.performFetch()
} catch let err as NSError {
print("Failed to fetch items", err)
}
}
@objc func addAlarmItem(_ sender: AnyObject) {
//print("this works")
let alertController = UIAlertController(title: "Add New Item", message: "Please fill in the blanks", preferredStyle: .alert)
let saveAction = UIAlertAction(title: "Save", style: .default) { [unowned self] action in
//combined string of attributes
let myStrings: [String] = alertController.textFields!.compactMap { [=12=].text }
let myText = myStrings.joined(separator: ", ")
self.save(myText)
self.tableView.reloadData()
}
let cancelAction = UIAlertAction(title: "Cancel", style: .destructive, handler: nil)
alertController.addTextField { (textField) in
textField.placeholder = "Enter Name of Engineer"
}
alertController.addTextField { (textField) in
textField.placeholder = "Enter Date of Alarm in DD/MM/YYYY"
}
alertController.addTextField { (textField) in
textField.placeholder = "Enter Time of Alarm in 24h (eg: 2300)"
}
alertController.addTextField { (textField) in
textField.placeholder = "Please indicate True/False (type True or False)"
}
alertController.addTextField { (textField) in
textField.placeholder = "Insert comments (if any), or NIL"
}
alertController.addAction(saveAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
func save(_ itemName: String) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "AlarmItems", in: managedContext)!
let item = NSManagedObject(entity: entity, insertInto: managedContext)
item.setValue(itemName, forKey: "alarmAttributes")
do {
try managedContext.save()
//NSFetchedResultsController.append(item)
tableView.reloadData()
} catch let err as NSError {
print("Failed to save an item", err)
}
}
@objc func exportCSV(_ sender: AnyObject) {
//will work on exporting csv in the future
return
}
override func numberOfSections(in tableView: UITableView) -> Int {
return fetchedResultsController.sections?.count ?? 0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
//return alarmItems.count
let sectionInfo = fetchedResultsController.sections![section]
return sectionInfo.numberOfObjects
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
let alarmItem = fetchedResultsController.object(at: indexPath)
cell.textLabel?.text = alarmItem.value(forKeyPath: "alarmAttributes") as? String
return cell
}
}
- 错误是:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An instance of NSFetchedResultsController requires a non-nil fetchRequest and managedObjectContext'
他们还说加载名为 AlarmItems 的模型失败,即使我的代码中已经有获取请求函数。
首先删除 let persistentContainer = NSPersistentContainer(name: "AlarmItems")
并从 AppDelegate
获取上下文
错误不完整
An instance of NSFetchedResultsController requires a non-nil fetchRequest with sort descriptors and managedObjectContext
fileprivate lazy var fetchedResultsController: NSFetchedResultsController<AlarmItems> = {
//create fetch request
let fetchRequest: NSFetchRequest<AlarmItems> = AlarmItems.fetchRequest()
//configure fetch request
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "alarmAttributes", ascending: true)]
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self
return fetchedResultsController
}()
如前所述,请以单数形式命名 NSManagedObject
子类 AlarmItem
我最近问了一个关于如何为我的 CoreData 实体实现删除功能的问题。 (这里:How do I delete CoreData entries in a tableview that uses a persistentcontainer?)我被告知我应该使用 NSFetchResultsController,所以我开始着手处理它。我以为我做对了我的代码现在在 运行.
后立即崩溃我试过使用教程来实现 FetchedResultsController。我很确定我已正确执行所有步骤以在我的应用程序中实施,但它仍然崩溃。我的尝试在下面提供。我的原始代码在上面的段落中。
ViewController.swift
import UIKit
import CoreData
class ViewController: UITableViewController {
//var alarmItems: [NSManagedObject] = []
let cellId = "cellId"
private let persistentContainer = NSPersistentContainer(name: "AlarmItems")
fileprivate lazy var fetchedResultsController: NSFetchedResultsController<AlarmItems> = {
//create fetch request
let fetchRequest: NSFetchRequest<AlarmItems> = AlarmItems.fetchRequest()
//configure fetch request
//fetchRequest.sortDescriptors = [NSSortDescriptor(key: )]
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.persistentContainer.viewContext, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self as? NSFetchedResultsControllerDelegate
return fetchedResultsController
}()
override func viewDidLoad() {
super.viewDidLoad()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
//guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
//let managedContext = appDelegate.persistentContainer.viewContext
//let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "AlarmItems")
do {
//alarmItems = try managedContext.fetch(fetchRequest)
try fetchedResultsController.performFetch()
} catch let err as NSError {
print("Failed to fetch items", err)
}
}
@objc func addAlarmItem(_ sender: AnyObject) {
//print("this works")
let alertController = UIAlertController(title: "Add New Item", message: "Please fill in the blanks", preferredStyle: .alert)
let saveAction = UIAlertAction(title: "Save", style: .default) { [unowned self] action in
//combined string of attributes
let myStrings: [String] = alertController.textFields!.compactMap { [=12=].text }
let myText = myStrings.joined(separator: ", ")
self.save(myText)
self.tableView.reloadData()
}
let cancelAction = UIAlertAction(title: "Cancel", style: .destructive, handler: nil)
alertController.addTextField { (textField) in
textField.placeholder = "Enter Name of Engineer"
}
alertController.addTextField { (textField) in
textField.placeholder = "Enter Date of Alarm in DD/MM/YYYY"
}
alertController.addTextField { (textField) in
textField.placeholder = "Enter Time of Alarm in 24h (eg: 2300)"
}
alertController.addTextField { (textField) in
textField.placeholder = "Please indicate True/False (type True or False)"
}
alertController.addTextField { (textField) in
textField.placeholder = "Insert comments (if any), or NIL"
}
alertController.addAction(saveAction)
alertController.addAction(cancelAction)
present(alertController, animated: true, completion: nil)
}
func save(_ itemName: String) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "AlarmItems", in: managedContext)!
let item = NSManagedObject(entity: entity, insertInto: managedContext)
item.setValue(itemName, forKey: "alarmAttributes")
do {
try managedContext.save()
//NSFetchedResultsController.append(item)
tableView.reloadData()
} catch let err as NSError {
print("Failed to save an item", err)
}
}
@objc func exportCSV(_ sender: AnyObject) {
//will work on exporting csv in the future
return
}
override func numberOfSections(in tableView: UITableView) -> Int {
return fetchedResultsController.sections?.count ?? 0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
//return alarmItems.count
let sectionInfo = fetchedResultsController.sections![section]
return sectionInfo.numberOfObjects
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath)
let alarmItem = fetchedResultsController.object(at: indexPath)
cell.textLabel?.text = alarmItem.value(forKeyPath: "alarmAttributes") as? String
return cell
}
}
- 错误是:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An instance of NSFetchedResultsController requires a non-nil fetchRequest and managedObjectContext'
他们还说加载名为 AlarmItems 的模型失败,即使我的代码中已经有获取请求函数。
首先删除 let persistentContainer = NSPersistentContainer(name: "AlarmItems")
并从 AppDelegate
错误不完整
An instance of NSFetchedResultsController requires a non-nil fetchRequest with sort descriptors and managedObjectContext
fileprivate lazy var fetchedResultsController: NSFetchedResultsController<AlarmItems> = {
//create fetch request
let fetchRequest: NSFetchRequest<AlarmItems> = AlarmItems.fetchRequest()
//configure fetch request
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "alarmAttributes", ascending: true)]
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = self
return fetchedResultsController
}()
如前所述,请以单数形式命名 NSManagedObject
子类 AlarmItem