NSFetchedResultsController 的部分数组元素的名称未正确更新
NSFetchedResultsController's sections array element's name not updating correctly
我有一个 NSFetchedResultsController 的简单用法定义了类似这个人为的例子
let request: NSFetchRequest<StudentEntity> = StudentEntity.fetchRequest()
request.sortDescriptors = [
NSSortDescriptor(key: "class.name", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))
]
fetchedResultsController = NSFetchedResultsController<StudentEntity>(
fetchRequest: request,
managedObjectContext: context,
sectionNameKeyPath: "class.name",
cacheName: nil)
这有助于 table 视图显示按 class 他们在 class 关系中设置的部分分组的学生实体。 class 实体具有名称属性,因此 sectionNameKeyPath 为 class.name。
当用户对学生引用的 class 进行编辑时,我尝试重新加载 table 中的数据,但不幸的是我发现我正在使用的部分名称不是更新。大量调试显示 class 实体当然可以正常更新,但由于某些原因,sections[].name 没有更新。我更新 class 名称如下
classEntity.name = newClassName
do
{
try context.save()
}
catch let error
{
dbgLog("failed to save context; error=\(error)")
}
tableView.reloadData();
这导致以下数据源方法正确运行
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
let sectionInfo = fetchedResultsController!.sections![section]
let sectionTitle = sectionInfo.name
let sectionStudentEntity = sectionInfo.objects![0] as! StudentEntity
let sectionTitleFromStudent = sectionStudentEntity.class!.name!
但是 sectionTitle 不会更新并显示旧的 class 名称,而 sectionTitleFromStudent 正确显示更新后的新 class 名称。
我假设这是因为 sectionNameKeyPath 是一个嵌套路径,虽然 class 实体正在更新,但 fetchedResultsController 不知何故没有检测到学生实体本身的任何变化,因此也没有检测到重新创建这些部分名称。感觉像是一个错误,但谢天谢地,我可以通过使用正确更新的 sectionTitleFromStudent 字符串来解决它。
有没有人有任何想法,或者自己遇到过同样的问题?
干杯
FetchedResultsController 将仅观察对其获取的实体对象的更改(在您的情况下为 Student
个对象)。所以它不知道相关 Class
对象的属性的变化。为了让它知道,您可以重做 performFetch
,这应该会触发它更新其获取的对象和部分。 (请注意,performFetch
绕过正常的 FRC 更改跟踪,因此 FRC 委托方法不会触发,但这应该不是问题,因为您正在对 tableView 执行完整的 reloadData
)。
我有一个 NSFetchedResultsController 的简单用法定义了类似这个人为的例子
let request: NSFetchRequest<StudentEntity> = StudentEntity.fetchRequest()
request.sortDescriptors = [
NSSortDescriptor(key: "class.name", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))
]
fetchedResultsController = NSFetchedResultsController<StudentEntity>(
fetchRequest: request,
managedObjectContext: context,
sectionNameKeyPath: "class.name",
cacheName: nil)
这有助于 table 视图显示按 class 他们在 class 关系中设置的部分分组的学生实体。 class 实体具有名称属性,因此 sectionNameKeyPath 为 class.name。
当用户对学生引用的 class 进行编辑时,我尝试重新加载 table 中的数据,但不幸的是我发现我正在使用的部分名称不是更新。大量调试显示 class 实体当然可以正常更新,但由于某些原因,sections[].name 没有更新。我更新 class 名称如下
classEntity.name = newClassName
do
{
try context.save()
}
catch let error
{
dbgLog("failed to save context; error=\(error)")
}
tableView.reloadData();
这导致以下数据源方法正确运行
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
let sectionInfo = fetchedResultsController!.sections![section]
let sectionTitle = sectionInfo.name
let sectionStudentEntity = sectionInfo.objects![0] as! StudentEntity
let sectionTitleFromStudent = sectionStudentEntity.class!.name!
但是 sectionTitle 不会更新并显示旧的 class 名称,而 sectionTitleFromStudent 正确显示更新后的新 class 名称。
我假设这是因为 sectionNameKeyPath 是一个嵌套路径,虽然 class 实体正在更新,但 fetchedResultsController 不知何故没有检测到学生实体本身的任何变化,因此也没有检测到重新创建这些部分名称。感觉像是一个错误,但谢天谢地,我可以通过使用正确更新的 sectionTitleFromStudent 字符串来解决它。
有没有人有任何想法,或者自己遇到过同样的问题?
干杯
FetchedResultsController 将仅观察对其获取的实体对象的更改(在您的情况下为 Student
个对象)。所以它不知道相关 Class
对象的属性的变化。为了让它知道,您可以重做 performFetch
,这应该会触发它更新其获取的对象和部分。 (请注意,performFetch
绕过正常的 FRC 更改跟踪,因此 FRC 委托方法不会触发,但这应该不是问题,因为您正在对 tableView 执行完整的 reloadData
)。