【问题标题】:NSFetchedResultsController: no object at index 2147483647NSFetchedResultsController:索引 2147483647 处没有对象
【发布时间】:2017-02-16 18:14:25
【问题描述】:

需要一个提示,在与 NSFetchedResultsController 苦苦挣扎几个小时后放弃。

错误信息是:

CoreData:错误:NSFetchedResultsController:索引处没有对象 2147483647 在索引 0 的部分

...但我什至不知道是谁触发了错误。我的最后一段代码是saveContext(),下一个断点在didChange里面。

class ViewController : UITableViewController, NSFetchedResultsControllerDelegate
private lazy var channelController: NSFetchedResultsController<ZChannel> = {

    let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate

    let request: NSFetchRequest<ZChannel> = ZChannel.fetchRequest()
    request.sortDescriptors = [NSSortDescriptor(key: "kit", ascending: true), NSSortDescriptor(key: "name", ascending: true)]

    let retval: NSFetchedResultsController<ZChannel> = NSFetchedResultsController(fetchRequest: request,
                                                                                 managedObjectContext: appDelegate.persistentContainer.viewContext,
                                                                                 sectionNameKeyPath: "kit",
                                                                                 cacheName: nil)
    retval.delegate = self

    return retval
}()

public init() {
    super.init(style: .grouped)

    self.tableView.register(ChannelTableCell.self, forCellReuseIdentifier: "ChannelTableCell")

    let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
    appDelegate.persistentContainer.viewContext.perform {
        do {
            try self.channelController.performFetch()
        } catch {
            let e = error as NSError
            fatalError("[CoreData] Unresolved fetch error \(e), \(e.userInfo)")
        }
    }
}   


public func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
    switch(type) {
    case .insert:
        self.tableView?.insertRows(at: [newIndexPath!], with: .bottom)
        break;
    case .update:
        self.tableView?.reloadRows(at: [indexPath!], with: .bottom)
        break
    default:
        break
    }
}

public func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
    switch (type) {
    case .insert:
        self.tableView?.insertSections(IndexSet(integer: sectionIndex), with: UITableViewRowAnimation.bottom)
        break
    case .delete:
        self.tableView?.deleteSections(IndexSet(integer: sectionIndex), with: UITableViewRowAnimation.bottom)
        break
    default:
        break
    }
}

我从另一个线程插入新对象:

self.persistentContainer.viewContext.performAndWait
{
    // ...
    let channel: ZChannel = NSEntityDescription.insertNewObject(forEntityName: "ZChannel", into: self.persistentContainer.viewContext) as! ZChannel
    // ...
    self.saveContext()
}

【问题讨论】:

  • UITableViewDataSource 和 NSFetchedResultsControllerDelegate 方法在哪里?

标签: ios swift core-data nsfetchedresultscontroller


【解决方案1】:

一些问题:

  • 2147483647 是 NSNotFound。如果您使用indexOfObject 之类的东西并假设它在数组中,然后使用将导致崩溃的索引。
  • 当您应该使用 newIndexPath 时,您正在使用 indexPath 进行行更新。原因是 indexPath 是任何插入或删除之前的索引,而 newIndexPath 是插入和删除之后的索引。
  • 没有理由在persistentContainer.viewContext.perform 内部调用self.channelController.performFetch() 你已经在主线程上

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-08
    • 1970-01-01
    • 2011-03-09
    • 2020-09-06
    • 2015-05-26
    • 1970-01-01
    相关资源
    最近更新 更多