2

我正在开发我的第一个 iPhone 应用程序(一个基本的待办事项列表应用程序),并且刚刚将 NSFetchResultsController 添加到我的表格视图中。我有 2 个行部分,添加行没有问题,它们按目标的已完成属性是否为 true 进行排序 - 如果是,则它进入底部并被划掉。

每当您在顶部的一行上向右滑动时,它会将目标的 complete 属性更改为 true 并将其移动到底部:

  RegimenGoal *goal = [_fetchedResultsController objectAtIndexPath:swipedIndexPath];
  goal.completed = [NSNumber numberWithBool:YES];

  [context save:&error];

这是我的视图控制器代码

出于某种原因,这仅适用于我刚刚创建的目标,但不适用于我添加的现有目标。经过一些调试,我意识到 NSFetchedResultsChangeMove 并没有被触发,而是 NSFetchedResultsChangeUpdate 是每当我对不是新的现有目标执行此操作时。

在 Apple 文档中也遇到过这个问题,“Moved Objects有时报告为已更新”。我通过简单地检查完成的属性是否为真来尝试了那里列出的解决方法。

当我这样做时,我发现 newIndexPath 不是新的——它只是旧的 indexPath,这让我很困惑……知道为什么会这样吗?

4

1 回答 1

1

创建获取的结果控制器时出错。如果通过指定将结果分组为部分sectionNameKeyPath:@"completed",则必须使用相同的键添加第一个排序描述符:

NSSortDescriptor *completeSort = [[NSSortDescriptor alloc] initWithKey:@"completed" ascending:YES];
NSSortDescriptor *daySort = [[NSSortDescriptor alloc] initWithKey:@"dateCreated" ascending:YES];
[dayRequest setSortDescriptors:[NSArray arrayWithObjects:completeSort, daySort, nil]];

另一个问题在tableView:cellForRowAtIndexPath:

[self configureCell:cell atIndexPath:indexPath];
[cell formatCell:indexPath.section];

在这里,您假设第 0 部分包含所有带有 的项目,completed = NO而第 1 部分包含所有带有 的项目completed = YES。但如果所有项目都完成了,那么只有一个部分(第 0 部分)包含所有已完成的项目。因此,您不能将indexPath.section其用作formatCell. 您应该改用 of 的值goal.completed。例如,您可以将formatCell调用移动到configureCell:atIndexPath:方法中:

- (void)configureCell:(RegimenCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    RegimenGoal *goal = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.label.text = goal.text;
    [cell formatCell:goal.completed.intValue];
}

reuseIdentifier现在让表格单元格依赖于节和行号已经没有多大意义了。我认为你可以更换

NSString *CellIdentifier = [NSString stringWithFormat:@"%d-%d", indexPath.row, indexPath.section];

通过固定字符串

NSString *CellIdentifier = @"YourCellIdentifer";

方法中也存在类似问题setNavTitle

int goalsCount = [_tableView numberOfRowsInSection:0];
int completedCount = [_tableView numberOfRowsInSection:1];

同样,如果所有目标都已完成,则它们都在第 0 节中,并且没有第 1 节。在这种情况下,您当前的代码将显示“(0%)”而不是“(100%)”。

进一步说明:

  • “移动的对象有时报告为更新”的解决方法在这里似乎不是必需的。
  • 对于NSFetchedResultsChangeUpdate事件,您可以调用[self configureCell:...][[_tableView reloadRowsAtIndexPaths:...]。不需要调用两者。
  • 实例变量_fetchedResultsController应仅在fetchedResultsController方法中使用,该方法根据需要创建获取的结果控制器 (FRC)。在所有其他地方,您应该使用self.fetchedResultsController以确保在必要时创建 FRC。
于 2012-12-22T10:26:37.273 回答