尝试创建简单的应用程序以显示从Core Data到Table View的数据。代码构建成功 - 每次加载时都会添加新条目,目前超过20条 - 但在尝试构建表时它会崩溃。
这里我有ViewController:
import UIKit
import CoreData
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var habitTable: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
let habitClassName:String = String(describing: Habits.self)
let habit:Habits = NSEntityDescription.insertNewObject(forEntityName: habitClassName, into: DatabaseController.getContext()) as! Habits
habit.habitsPic = ":("
habit.positive = false
habit.theHabit = "do bad"
DatabaseController.saveContext()
let fetchRequest:NSFetchRequest<Habits> = Habits.fetchRequest()
do{
let searchResults = try DatabaseController.getContext().fetch(fetchRequest)
print("number of results: \(searchResults.count)")
}
catch{
print("Error \(error)")
}
}
//CONSTRUCT TABLE VIEW
func numberOfSectionsInTableView(tableView: UITableView)-> Int {
return fetchedResultsController.sections!.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let sections = fetchedResultsController.sections else {
fatalError("No sections in fetchedResultsController")
}
let sectionInfo = sections[section]
return sectionInfo.numberOfObjects
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)-> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "positiveCell", for: indexPath as IndexPath)
let habit = fetchedResultsController.object(at: indexPath as IndexPath) as! Habits
cell.textLabel?.text = habit.theHabit
cell.detailTextLabel?.text = habit.habitsPic
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
//FOR DISPLAYING DATA IN TABLE
var fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>!
func initializeFetchedResultsController() {
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Habits")
let departmentSort = NSSortDescriptor(key: "theHabit", ascending: true)
let lastNameSort = NSSortDescriptor(key: "positive", ascending: true)
request.sortDescriptors = [departmentSort, lastNameSort]
let moc = DatabaseController.getContext()
fetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: moc, sectionNameKeyPath: nil, cacheName: nil)
fetchedResultsController.delegate = (self as! NSFetchedResultsControllerDelegate)
do {
try fetchedResultsController.performFetch()
} catch {
fatalError("Failed to initialize FetchedResultsController: \(error)")
}
}
}
和DatabaseController:
import Foundation
import CoreData
class DatabaseController {
private init(){
}
class func getContext() -> NSManagedObjectContext{
return DatabaseController.persistentContainer.viewContext
}
let container = NSPersistentContainer(name: "ada")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
class func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}
它不会构建表视图,因为fetchedResultsController返回nil。我认为这是“moc”变量的问题,但是什么?
修改
错误: 致命错误:在解包可选值时意外发现nil
订单: guard let sections = fetchedResultsController.sections else {
答案 0 :(得分:2)
您将获取的结果控制器声明为隐式解包的可选项:
var fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>!
其初始值为零。
您还有一个名为initializeFetchedResultsController
的方法,可以为此属性指定值,但您永远不会调用该方法。在评论中,您说您在此代码中调用它:
guard let sections = fetchedResultsController.sections else {
fatalError("No sections in fetchedResultsController")
}
但该代码从未提及initializeFetchedResultsController
方法,因此它从不调用该方法。
您有一个可选变量,但您从不为其赋值。所以它永远不会有价值。所以它没有。这不是核心数据问题,它是基本的Swift。除非您给出值,否则属性不会获取值,而您没有这样做。