HTML5   发布时间:2022-04-27  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了ios – 核心数据,在实体上设置关系会导致获取结果控制器委托回调中的错误大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
(实体名称已更改,以便更容易阅读)

环境:Xcode 7 beta 4. iOS 9.0是Base SDK,部署目标是iOS 8.0.在运行iOS 8.4的iPhone 5s真实设备上进行调试.

这是一个有趣的核心数据错误,我花了最近几天调试/尝试理解.

我已经建立了一个实体RecipeEntity,它具有一些属性和与实体IngredientEntity的多对多关系来表示它的成分. IngredientsEntity与RecipeEntity具有对应的反向关系,两个实体都在关系上设置了以下属性

ios – 核心数据,在实体上设置关系会导致获取结果控制器委托回调中的错误

一个视图控制器,它有一个显示成分的表视图,并使用NSFetchedResultsController获取单元格的数据,NSFetchedResultsControllerDelegate设置为视图控制器本身.

以下是用于获取结果控制器委托的原始代码

// MARK: - FetchedResultsController Delegate

/*
We're using a nifty solution to fix the issue of multiple Core Data changes occuring at the same time.
See here for an explanation of why and how it works:
http://www.fruitstandsoftware.com/blog/2013/02/19/uitableview-and-nsfetchedresultscontroller-updates-done-right/
*/

private var deletedSectionIndexes = NSMutableIndexSet()
private var insertedSectionIndexes = NSMutableIndexSet()
private var deletedRowIndexPaths = [NSIndexPath]()
private var insertedRowIndexPaths = [NSIndexPath]()
private var updatedRowIndexPaths = [NSIndexPath]()

func controller(controller: NSFetchedResultsController,didChangeObject anObject: NsmanagedObject,aTindexPath indexPath: NSIndexPath?,forChangeType type: NSFetchedResultsChangeType,newIndexPath: NSIndexPath?) {
    switch type {
    case NSFetchedResultsChangeType.Insert:
        if let newIndexPath = newIndexPath {
            if insertedSectionIndexes.containsIndex(newIndexPath.section) {
                // If we've already been told that we're adding a section for this inserted row we skip it since it will handled by the section insertion.
                return
            }
            insertedRowIndexPaths.append(newIndexPath)
        }
    case NSFetchedResultsChangeType.delete:
        if let indexPath = indexPath {
            if deletedSectionIndexes.containsIndex(indexPath.section) {
                // If we've already been told that we're deleting a section for this deleted row we skip it since it will handled by the section deletion.
                return
            }
            deletedRowIndexPaths.append(indexPath)
        }
    case NSFetchedResultsChangeType.Move:
        if let newIndexPath = newIndexPath {
            if !insertedSectionIndexes.containsIndex(newIndexPath.section) {
                insertedRowIndexPaths.append(newIndexPath)
            }
        }
        if let indexPath = indexPath {
            if !deletedSectionIndexes.containsIndex(indexPath.section) {
                deletedRowIndexPaths.append(indexPath)
            }
        }
    case NSFetchedResultsChangeType.update:
        if let indexPath = indexPath {
            updatedRowIndexPaths.append(indexPath)
        }
    }
}

func controller(controller: NSFetchedResultsController,didChangeSection sectionInfo: NSFetchedResultsSectionInfo,aTindex sectionIndex: Int,forChangeType type: NSFetchedResultsChangeTypE) {
    switch type {
    case NSFetchedResultsChangeType.Insert:
        insertedSectionIndexes.addIndex(sectionIndeX)
    case NSFetchedResultsChangeType.delete:
        deletedSectionIndexes.addIndex(sectionIndeX)
    default:
        break
    }
}

func controllerDidChangeContent(controller: NSFetchedResultsController) {
    tableView.beginupdates()

    tableView.deleteSections(deletedSectionIndexes,withRowAnimation: UITableViewRowAnimation.AutomatiC)
    tableView.insertSections(insertedSectionIndexes,withRowAnimation: UITableViewRowAnimation.AutomatiC)

    tableView.deleteRowsATindexPaths(deletedRowIndexPaths,withRowAnimation: UITableViewRowAnimation.Left)
    tableView.insertRowsATindexPaths(insertedRowIndexPaths,withRowAnimation: UITableViewRowAnimation.Right)
    tableView.reloadRowsATindexPaths(updatedRowIndexPaths,withRowAnimation: UITableViewRowAnimation.AutomatiC)

    tableView.endupdates()

    // Clear the collections so they are ready for their next use.
    insertedSectionIndexes = NSMutableIndexSet()
    deletedSectionIndexes = NSMutableIndexSet()
    deletedRowIndexPaths = [NSIndexPath]()
    insertedRowIndexPaths = [NSIndexPath]()
    updatedRowIndexPaths = [NSIndexPath]()
}

问题是当设置recipeEntity与之关系的IngredientEntity时,会发生以下故障:

我最终将其跟踪到控制器:didChangeObject:aTindexPath:forChangeType:newIndexPath:使用更改类型NSFetchedResultsChangeType.Move调用,但indexPath和newIndexPath都使用相同的NSIndexPath.

这里大致是将实体添加为关系的代码

// setOfIngredients is an NSSet of IngredientEntity's retreived from Core Data.
recipeEntity.ingredients = setOfIngredients

将此switch case语句(在控制器中:didChangeObject:aTindexPath:forChangeType:newIndexPath:delegate方法)更改为以下内容解决此问题:

case NSFetchedResultsChangeType.Move:
        // If the indexPath and the newIndexPath are the same,then they shouldn't really be deleted and inserted,the row should just be reloaded,// otherwise it causes a crash.
        if indexPath != newIndexPath {
            if let newIndexPath = newIndexPath {
                if !insertedSectionIndexes.containsIndex(newIndexPath.section) {
                    insertedRowIndexPaths.append(newIndexPath)
                }
            }
            if let indexPath = indexPath {
                if !deletedSectionIndexes.containsIndex(indexPath.section) {
                    deletedRowIndexPaths.append(indexPath)
                }
            }
        } else if let indexPath = indexPath {
            updatedRowIndexPaths.append(indexPath)
        }

主要问题:

那么为什么要在Core Data实体对象上设置关系的值会导致控制器:didChangeObject:aTindexPath:forChangeType:newIndexPath:用更改类型调用.移动但是相同的新旧索引路径?

这是Xcode 7 beta 4 / Swift 2.0中的错误还是我做错了什么?

我真的很想知道这里发生了什么,我花了几天时间尝试调试,所以感谢你的帮助!

让我知道,如果有任何更多的信息,我可以提供,这将是有益的,谢谢.

解决方法

我想知道这是否是因为.当对象的已更改属性获取请求中使用的排序描述符之一时,会报告移动更改.

我看到indexPath和newIndexPath也经常相同.根据文档,这被认为也是隐式更新.

来自NSFetchedResultsController.h

The Move object is reported when the changed attribute on the 
object is one of the sort descriptors used in the fetch request. 
An update of the object is assumed in this case,but no separate 
update message is sent to the delegate.

大佬总结

以上是大佬教程为你收集整理的ios – 核心数据,在实体上设置关系会导致获取结果控制器委托回调中的错误全部内容,希望文章能够帮你解决ios – 核心数据,在实体上设置关系会导致获取结果控制器委托回调中的错误所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。