全屏表格视图iPad应用程序。我已经在我的行上启用了滑动删除。行动画始终在删除后完成(commitEditingStyle完成),但偶尔整个表视图会冻结。注意,不是整个UI,因此不是阻止主线程。我能够点击列标题或导航控制器上的返回按钮,但表本身被锁定并且无法滑动。我可以通过轻松点击其中一个列标题按钮来解除冻结。
我完全不知道是什么原因导致了冻结。我正在使用NSFetchedResultsController,这是我的委托代码。它相当基础 (更新: 现在不再是基础的了。使用分批处理方法):
// MARK: NSFetchedResultsController delegate methods
lazy var deletedSectionIndexes : NSMutableIndexSet = {
return NSMutableIndexSet()
}()
lazy var insertedSectionIndexes : NSMutableIndexSet = {
return NSMutableIndexSet()
}()
lazy var deletedRowIndexPaths : [NSIndexPath] = {
return [NSIndexPath]()
}()
lazy var insertedRowIndexPaths : [NSIndexPath] = {
return [NSIndexPath]()
}()
lazy var updatedRowIndexPaths : [NSIndexPath] = {
return [NSIndexPath]()
}()
func controllerWillChangeContent(controller: NSFetchedResultsController) {
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch(type) {
case .Delete:
if let indexPath = indexPath {
self.deletedRowIndexPaths.appendDistinct(indexPath)
}
case .Update:
if let indexPath = indexPath {
self.updatedRowIndexPaths.appendDistinct(indexPath)
}
case .Insert:
if let newIndexPath = newIndexPath {
self.insertedRowIndexPaths.appendDistinct(newIndexPath)
}
case .Move:
if let indexPath = indexPath, newIndexPath = newIndexPath {
self.insertedRowIndexPaths.appendDistinct(newIndexPath)
self.deletedRowIndexPaths.appendDistinct(indexPath)
}
}
}
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
switch(type) {
case .Delete:
self.deletedSectionIndexes.addIndex(sectionIndex)
case .Insert:
self.insertedSectionIndexes.addIndex(sectionIndex)
default:
break
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
self.tableView.beginUpdates()
self.tableView.insertSections(self.insertedSectionIndexes, withRowAnimation: .None)
self.tableView.deleteSections(self.deletedSectionIndexes, withRowAnimation: .None)
self.tableView.insertRowsAtIndexPaths(self.insertedRowIndexPaths, withRowAnimation: .None)
self.tableView.deleteRowsAtIndexPaths(self.deletedRowIndexPaths, withRowAnimation: .None)
self.tableView.reloadRowsAtIndexPaths(self.updatedRowIndexPaths, withRowAnimation: .None)
self.tableView.endUpdates()
self.insertedSectionIndexes.removeAllIndexes()
self.deletedSectionIndexes.removeAllIndexes()
self.deletedRowIndexPaths.removeAll()
self.insertedRowIndexPaths.removeAll()
self.updatedRowIndexPaths.removeAll()
}
在didChangeObject代理方法中调用了delete,但从技术上讲,这不是真正的删除。我只是将属性设置为-1,然后通过NSMangagedObjectContext保存该元素 - 在此时,NSFRC似乎会执行正确的操作,即从使用此谓词获取的获取对象列表中将其删除:
NSPredicate(format: "account = %@ and quantity != -1", account)
其中account
是一个有效的帐户管理对象。90%或更多的时间,该行可以顺利消失。只是偶尔在动画完成后,表格会以我所描述的方式冻结。它永远不会在删除按钮仍然显示时冻结,因此我知道它是在调用commitEditingStyle之后发生的。删除按钮没有自定义实现。它是UITableView默认的滑动删除实现。以下是我的commitEditingStyle方法:
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
if let frameboardItem = self.fetchedResultsController.objectAtIndexPath(indexPath) as? IRMFrameBoardItemMO {
if frameboardItem.isNew {
// If it's never been pushed to the server, just delete locally. This will trigger a table reload
// via NSFetchedResultsController
DataManager.mainContext.deleteObject(frameboardItem)
} else {
// Otherwise mark it with a negative quantity which tells the server to delete it and tells the
// app to hide it.
frameboardItem.quantity = -1
}
do {
try DataManager.mainContext.save()
} catch let error as NSError {
dLog("Something went wrong: \(error.localizedDescription)")
}
}
}
}
你可以在这里看到一个视频,它与我所说的内容有关。由于时长超过两分钟,你可能不想看完整个视频,但我会将其放在这里供参考。
我很乐意听取任何建议。
更新
我已经更新了NSFRC代理方法,采用批处理方法以确保所有更新一次性应用。但这并没有解决问题。表格仍然会定期冻结。
frameboardItem
为nil
的情况:if let frameboardItem = self.fetchedResultsController.objectAtIndexPath(indexPath) as? IRMFrameBoardItemMO
?如果是nil
,那么表格是否会在不更新数据源的情况下被更新? - Alexander