大家好,你好,
我有以下问题并尝试解决数小时。 感觉就像我的CoreData / FetchResultsController有些不对劲。
我有以下代码:
import UIKit
import CoreData
class SavedActivitiesViewController: UITableViewController, NSFetchedResultsControllerDelegate {
var managedObjectContext: NSManagedObjectContext? = nil
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.fetchedResultsController.sections!.count ?? 0
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("ActivityCell") as! ActivityCell
let activity = self.fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject
self.configureCell(cell, withObject: activity)
return cell
}
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
let context = self.fetchedResultsController.managedObjectContext
context.deleteObject(self.fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject)
do {
try context.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
//print("Unresolved error \(error), \(error.userInfo)")
abort()
}
}
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath){
let activityView = self.storyboard?.instantiateViewControllerWithIdentifier("ActivityView") as! ActivityViewController
let activityViewNav = UINavigationController(rootViewController: activityView)
let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.drawerContainer!.centerViewController = activityViewNav
appDelegate.drawerContainer!.toggleDrawerSide(DrawerSide.Left, animated: true, completion: nil)
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 80.0
}
func configureCell(cell: UITableViewCell, withObject object: NSManagedObject) {
let activity = object as! Activity
let cell = cell as! ActivityCell
cell.shortTitle.text = activity.valueForKey("shortTitle") as? String
}
// MARK: - Fetched results controller
var fetchedResultsController: NSFetchedResultsController {
if _fetchedResultsController != nil {
return _fetchedResultsController!
}
let fetchRequest = NSFetchRequest()
// Edit the entity name as appropriate.
let entity = NSEntityDescription.entityForName("Activity", inManagedObjectContext: self.managedObjectContext!)
fetchRequest.entity = entity
// Set the batch size to a suitable number.
fetchRequest.fetchBatchSize = 20
// Edit the sort key as appropriate.
let sortDescriptor = NSSortDescriptor(key: "activityID", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext!, sectionNameKeyPath: nil, cacheName: "Master")
aFetchedResultsController.delegate = self
_fetchedResultsController = aFetchedResultsController
do {
try _fetchedResultsController!.performFetch()
} catch {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
//print("Unresolved error \(error), \(error.userInfo)")
abort()
}
return _fetchedResultsController!
}
var _fetchedResultsController: NSFetchedResultsController? = nil
func controllerWillChangeContent(controller: NSFetchedResultsController) {
self.tableView.beginUpdates()
}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
switch type {
case .Insert:
self.tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
case .Delete:
self.tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade)
default:
return
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case .Insert:
tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade)
case .Delete:
tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade)
case .Update:
self.configureCell(tableView.cellForRowAtIndexPath(indexPath!)!, withObject: anObject as! NSManagedObject)
case .Move:
tableView.moveRowAtIndexPath(indexPath!, toIndexPath: newIndexPath!)
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
self.tableView.endUpdates()
}
出于某种原因,我的应用程序会在启动时崩溃:
2016-08-04 16:47:29.546 TestApp [2527:852314] *由于未捕获的异常'NSRangeException'而终止应用程序,原因:'* - [_ PFBatchFaultingArray objectAtIndex:]:index( 0)超出界限(0)' ***首先抛出调用堆栈:
...
libc ++ abi.dylib:以NSException类型的未捕获异常终止 (LLDB)
如果我为其中断的所有异常启用了断点:
let activity = self.fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject
使用cellForRowAtIndexPath 的tableView方法中的
当我打印self.fetchedResultsController.sections!.count
它说1
但是当我不保存任何内容时,它不应该打印0
吗? (我在模拟器上删除了应用程序,因此我的CoreData应该被删除)
当我设置
的返回时 override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.fetchedResultsController.sections!.count ?? 0
}
到0我的应用程序正在运行。如果我现在通过App将对象保存到我的coreData中,我可以将返回设置回return self.fetchedResultsController.sections!.count ?? 0
它又重新开始了。但我只能保存这一个对象。
我收到以下消息:
2016-08-04 17:14:40.407 TestApp [2582:984402] ***断言失败 - [UITableView _endCellAnimationsWithContext:],/ BuildRoot / Library / Cache / com.apple.xbs / Source / UIKit_Sim / UIKit -3512.60.7 / UITableView.m:1502 2016-08-04 17:14:40.408 TestApp [2582:984402] CoreData:错误:严重的应用程序错误。在调用-controllerDidChangeContent:期间,从NSFetchedResultsController的委托中捕获到异常。尝试将第10行插入第0部分,但在使用userInfo(null)更新后第0部分中只有1行
第10行来自多次点击“保存”按钮。 我不知道自己做错了什么,我使用了一本解释coreData的书,并将其与互联网上的例子进行了比较。
你们是我最后的希望。