确保将sectionKeyPathName
值(来自相关实体)的更改传播到UITableView的节标题(包括包括使用新值重绘节标题并在需要时更改节顺序)的最佳实践是什么?
我假设NSFetchedResultsController委托的当前功能无法满足我的需求,因为NSFetchedResultsController
观察一个实体(在本例中为表行的食谱),而不是sectionKeyPathName
的实体(我的类别名称属性)。NSFetchedResultsController
委托的controller(_:didChange:atSectionIndex:for)
从不返回其类型参数的移动或更新
背景
我有两个实体,类别和食谱,其中一个类别可以具有多个食谱,而一个食谱将仅属于1个类别(又称1:M关系)。
我有一张食谱的表格视图,每个类别都有一个部分。部分标题是类别的名称。我使用了fetchedResultsController来填充表格视图。一切都按预期完成(即,在更新,添加,删除配方或更改其类别时,表格视图会反映出这些更改),并且具有一个例外。当类别名称更改时,我无法更改节标题。我不仅希望标题反映更改后的名称,还希望根据需要重新排序。
代码段
我会根据需要分享。正如我所说,其他所有方法都可以正常工作,并且有很多代码。
FWIW-我的sectionKeyPathName
值与sortDescriptor数组的第一个值相同。
尝试失败
我假设我需要观察Category的name
属性进行更改。最坏的情况是,我的部分需要重新排序。因此,如果name
更改了,我将再次performFetch()
然后在表上reloadData()
。我尝试了这种技术。
观察NSManagedObjectContextWillSave
以确定类别(当前是我的表视图中的一部分)是否具有其name
属性更改。
如果name
属性更改,那么当我观察到NSManagedObjectContextDidSave
时,我将再次执行访存并重新加载Data()。这似乎解决了问题,但是当我测试将配方移到其他类别时崩溃了。 (移动测试在进行此更改之前已经起作用。)(崩溃为An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of sections.
)
最佳答案
fetchedResultsController很棒。但是他们不是超级聪明。它们仅监视设置为要获取的实体的更改。它假定所有其他更改均不影响它。因此,如果您有基于关系的谓词或排序描述符,则可能会引起问题。
可能的解决方案:
1)列出类别而不是食谱
即使将fetchedResultsController设计为在Tableview或collectionView的1:1设置中也能很好地工作(即,fetchedResultsController的indexPath等于视图的indexPath),它也不需要那样工作。
您可以为没有sectionKeyPathName的类别创建fetchedResultsController。然后设置节数为控制器中的项目数。每个部分中的项目数等于每个类别中的食谱数。
如果您有一个谓词来过滤配方,这将变得更加困难。
2)发生更改时触发fetchedResultsController
如果仅在少数几个地方更改类别,则可能很容易简单地“弄脏”类别中的所有配方以触发fetchedResultsController。如果将属性设置为等于自身(即r.recipeId = r.recipeId),它将触发fetchedResultsController中的更新。因此,当您更改categoryName时,还要遍历所有配方并将它们弄脏。
3)有两个fetchedResultsController
FetchedResultsController是非常轻便的对象,您无需担心要制作多少。您可以创建两个。一种用于食谱,另一种用于类别。这些部分基于类别fetchedResultsController。对于配方fetchedResultsController,您可以根据不变的类别属性(例如categoryId)将其分组。然后,当您想知道某个类别的numberOfRows时,必须在配方fetchedResultsController中找到它。弄清楚indexPath可能会有些烦人-但是,如果您创建一个单独的对象来管理它,则没什么大不了的。
如果您要显示所有食谱,我将推荐#1。如果您对自己的食谱有疑问,我会推荐#2。如果您是代码纯粹主义者,并且希望将模型和视图完全分开,我只会建议#3。
关于ios - 从关系中观察到sectionNameKeyPath的变化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45656165/