填充当有2个部分时,CoreData中的行数

在我的CoreData中,我有一个Person实体,每个Person可以有多个(to Many)Statement实体。 语句实体有一个名为amountOwed的属性,它是一个十进制数量。 现在我的想法是循环所有金额并将它们加起来,如果它们是正数量将它们添加到正数组,如果它们是负数,则将它们添加到该数组。 然后使用该数组来确定每个部分需要显示多少个单元格。

我创建了一个fetchedResultsController ,我正在尝试将其用于for循环

 for i in 0..<fetchedResultsController.fetchedObjects!.count { let person = fetchedResultsController.fetchedObjects?[i] let amountTotal = person?.value(forKeyPath: "statement.@sum.amountOwed") as? Decimal if(amountTotal! <= Decimal(0) ) { postiveCellNumber += 1 print("\(postiveCellNumber) postive number count") } else{ negativeCellNumber += 1 print("\(negativeCellNumber) negative number count") } } 

然后,我试图在numberOfRowsInSection函数中使用这些数组,如下所示:

  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { switch(section) { case 0: return postiveCellNumber case 1: return negativeCellNumber default :return 0 } } 

我不认为我的for循环正常循环,因为我得到一个错误

索引0处的索引2处没有对象。

如何使用两个不同的查询,一个用于正值,一个用于负值,两个不同的获取结果控制器? 然后你可以让FRC为你做迭代和计数。

您将无法使用FRC管理部分。 你必须自己做。 为sectionNameKeyPath指定nil 。 然后你想要类似的东西

 func numberOfSections(in tableView: UITableView) -> Int { return 2 } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if section == 0 { return positiveResultsController.fetchedObjects?.count ?? 0 } else { return negativeResultsController.fetchedObjects?.count ?? 0 } } 

或者可能

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if section == 0 { let sectionInfo = positiveResultsController.sections![section] return sectionInfo.numberOfObjects } else { let sectionInfo = negativeResultsController.sections![section] return sectionInfo.numberOfObjects } } 

tableView(_:cellForRowAt:)逻辑相似。

如果不了解FRC和tableView的构造方式,就很难确定错误的具体原因。 但这一点看起来很可疑:

  if(amountTotal! <= Decimal(0) ) { postiveCellNumber += 1 print("\(postiveCellNumber) postive number count") } 

当然if条件会回到前面:如果amountTotal! >= Decimal(0)你应该增加amountTotal! >= Decimal(0) amountTotal! >= Decimal(0)

但除此之外,即使您成功计算了计数,您也将面临解决FRC的fetchedObjects应出现在每个部分的每一行中的问题:

  • 你可以在cellForRowAt “动态”执行此操作,但这将涉及再次遍历fetchedObjects,以确定哪个部分出现在哪个部分,这是笨拙和低效的。
  • 一旦FRC完成了performFetch,您就可以将fetchedObjects分成两个独立的数组作为一次性步骤。 但是,每当FRC的fetchedObjects数组更新时,您需要非常难看的FRC委托方法来更新两个数组。
  • 您可以通过为基础提取指定sectionNameKeyPath和关联的排序描述符,将FRC配置为自动将其提取的对象分配给正确的部分。 这里的问题是无法使用计算的数字对提取进行排序。 如果要继续使用此路由,则需要向Person实体添加totalAmountOwed属性,并确保在相关Statements发生更改时更新该属性。
  • 或者,您可以按照@ HalMueller的建议,使用两个单独的FRC。 您可以使用补充谓词进行基础提取,一个只获得欠负数的人,另一个获得欠负数的人。 然后,您可以使用fetchedObjects数组为一个FRC填充第0部分,使用另一个FRC填充第1部分。总的来说,我认为这是我建议的解决方案。