NSFetchedResultsController:索引 2147483647 处没有对象
NSFetchedResultsController: no object at index 2147483647
需要提示,在与 NSFetchedResultsController 纠缠数小时后放弃。
错误信息是:
CoreData: error: NSFetchedResultsController: no object at index
2147483647 in section at index 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()
}
一些问题:
- 2147483647 是 NSNotFound。如果您使用
indexOfObject
之类的东西并假设它在数组中,然后使用将导致崩溃的索引。
- 当您应该使用 newIndexPath 时,您正在使用 indexPath 进行行更新。原因是 indexPath 是任何插入或删除之前的索引,而 newIndexPath 是插入和删除之后的索引。
- 没有理由在里面调用
self.channelController.performFetch()
persistentContainer.viewContext.perform
你已经在主线程了
需要提示,在与 NSFetchedResultsController 纠缠数小时后放弃。
错误信息是:
CoreData: error: NSFetchedResultsController: no object at index 2147483647 in section at index 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()
}
一些问题:
- 2147483647 是 NSNotFound。如果您使用
indexOfObject
之类的东西并假设它在数组中,然后使用将导致崩溃的索引。 - 当您应该使用 newIndexPath 时,您正在使用 indexPath 进行行更新。原因是 indexPath 是任何插入或删除之前的索引,而 newIndexPath 是插入和删除之后的索引。
- 没有理由在里面调用
self.channelController.performFetch()
persistentContainer.viewContext.perform
你已经在主线程了