我一直在遇到错误时实现nsfetchedresultscontroller感到困惑。我正在尝试将核心数据与uitaiteView连接起来,并且我没有根据core Data中的记录数量来绘制正确数量的行来绘制正确数量的行。我收到此错误消息:
*** Terminating app
due to uncaught exception 'NSRangeException', reason: '***
[__NSSingleObjectArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
这是我的代码:
import UIKit
import CoreData
class CustomerProfileViewController: UITableViewController, NSFetchedResultsControllerDelegate {
var coreDataStack: CoreDataStack!
var itemList: [NSManagedObject] = [] // I hope to have the fetch results controller manage this object
// The data model contains one entity "Item" with one attribute "name"
lazy var fetchResultsControllerItem: NSFetchedResultsController<Item> = {
// Initialize Fetch Request
let fetchRequest: NSFetchRequest<Item> = Item.fetchRequest()
// Configure Fetch Request
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
// Initialize Fetch Results Controller
let fetchResultsControllerItem =
NSFetchedResultsController(fetchRequest: fetchRequest,
managedObjectContext: self.coreDataStack.managedContext,
sectionNameKeyPath: nil,
cacheName: nil)
fetchResultsControllerItem.delegate = self
return fetchResultsControllerItem
}()
override func viewDidLoad() {
super.viewDidLoad()
do {
try fetchResultsControllerItem.performFetch()
print("Fetch worked! 🐺")
} catch let error as NSError {
print("Could not save. (error), (error.userInfo)")
}
let cellNib = UINib(nibName: "SummaryCell", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "SummaryCell")
let cellNib = UINib(nibName: "ListingsCell", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "ListingsCell")
}
override func numberOfSections(in tableView: UITableView) -> Int {
return 2 // Corresponds to the custom table view cells as Nib files
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section == 0 {
return "SUMMARY"
} else if section == 1 {
return "ITEM LISTINGS"
} else {
return ""
}
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 1
} else if section == 1 {
/* Adding the "guard let sections" to the "return
sectionInfo.numberOfObject" below causes an error: *** Terminating app
due to uncaught exception 'NSRangeException', reason: '***
[__NSSingleObjectArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]' */
enter code here
guard let sections = fetchResultsControllerItem.sections else {
return 0
}
let sectionInfo = sections[section]
return sectionInfo.numberOfObjects
} else {
return 1
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "SummaryCell", for: indexPath) as! SummaryCell
cell.totalNumberOfItems?.text = "(itemList.count)"
return cell
} else if indexPath.section == 1 {
let cell = tableView.dequeueReusableCell(withIdentifier: "ListingsCell", for: indexPath) as! ListingsCell
let listItem = fetchResultsControllerItem.object(at: indexPath)
cell.itemName?.text = listItem.name
return cell
}
return UITableViewCell()
}
}
下面显示包含coredatastack实现的文件:
import Foundation
import CoreData
class CoreDataStack {
private let modelName: String
init(modelName: String) {
self.modelName = modelName
}
lazy var managedContext: NSManagedObjectContext = {
return self.storeContainer.viewContext
}()
private lazy var storeContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: self.modelName)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
print("Unresolved error (error), (error.userInfo)")
}
})
return container
}()
func saveContext() {
guard managedContext.hasChanges else { return }
do {
try managedContext.save()
} catch let error as NSError {
print("Unresolved error (error), (error.userInfo)")
}
}
}
我确实使用了liya来确认在检查sqlite文件后有记录的名称。对于有任何提示或想法的人,我都将感谢任何帮助。谢谢。
问题是,在fetchedresultscontroller的视图中,如果世界只有一个部分:第0部分:第0节。但是,您的tableview有两个部分,您希望FRC为数据提供数据第1节。因此,您需要将FRC INDEXPATHS重新映射到表视图中的正确部分,在表观视图dataSource方法中。因此,在numberOfRowsInSection
中,您的代码当前正在向FRC询问第1节中的对象数量,而FRC会引发错误,因为就其而言,没有第1节。只需替换:
let sectionInfo = sections[section]
return sectionInfo.numberOfObjects
with:
let sectionInfo = sections[0]
return sectionInfo.numberOfObjects
在该方法中。然后在cellForRowAt
中替换以下:
let cell = tableView.dequeueReusableCell(withIdentifier: "ListingsCell", for: indexPath) as! ListingsCell
let listItem = fetchResultsControllerItem.object(at: indexPath)
cell.itemName?.text = listItem.name
return cell
与此:
let cell = tableView.dequeueReusableCell(withIdentifier: "ListingsCell", for: indexPath) as! ListingsCell
let listItem = fetchResultsControllerItem.fetchedObjects![indexPath.row]
cell.itemName?.text = listItem.name
return cell
(这使用FRC的fetchedObjects
属性避免使用object(at:)
中的IndexPath中的错误部分(。