nsfetchedresultscontroller问题:索引1超越界限,管理自定义表视图单元格



我一直在遇到错误时实现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中的错误部分(。

相关内容

  • 没有找到相关文章

最新更新