如何刷新NSFetchedResultsController?

Sen*_*ful 2 cocoa-touch core-data objective-c nspredicate nsfetchedresultscontroller

我有一个NSFetchedResultsController,它在UITableView中显示数据.在选择创建Core Data项目时,我正在使用Xcode提供的样板代码.我将以下谓词添加到NSFetchedResultsController使用的NSFetchRequest中(在NSFetchedResultsController初始化之前):

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"deleted == NO"];
[fetchRequest setPredicate:predicate];
Run Code Online (Sandbox Code Playgroud)

现在在我的应用程序的另一个位置,我像这样设置已删除的属性(伪代码):

myManagedObject.deleted = YES
saveDataContext
Run Code Online (Sandbox Code Playgroud)

当我返回TableViewController时,它仍然显示这个"已删除"的行.

当我尝试重新加载表视图时,没有任何反应.

当我尝试使用时重新加载fetchedResultsController时performFetch,它说:

'致命错误:部分信息的持久缓存与当前配置不匹配.您已经非法改变了NSFetchedResultsController的获取请求,其谓词或其排序描述符,而无需禁用缓存或使用+ deleteCacheWithName:'

如果我删除缓存,在init方法中调用performFetch,然后调用[myTable reloadData]它.

是不是有更简单的方法来刷新数据?最好是允许你使用NSFetchedResultsController的缓存功能吗?

据我所知,我修改获取请求,谓词或排序描述符的唯一地方是在分配和插入NSFetchedResultsController的相同方法中,因此它显示的错误消息似乎不正确.

更新:现在我理解NSFetchedResultsController了一点,我明白它不会自动删除行,而且它controller:didChangeObject:atIndexPath:forChangeType:nowIndexPath:是主要负责删除行的方法.我已经实现了这个方法,因为我在项目中使用了Apple的模板.

但是,在我的情况下,我实际上并没有删除一个项目,我只是更新一个property(deleted)来指定该项目不再存在于列表中.这意味着该controller:didChangeObject:atIndexPath:forChangeType:nowIndexPath:方法的改变类型为NSFetchedResultsChangeUpdate,而不是NSFetchedResultsChangeDelete.我将代码更新为:

  case NSFetchedResultsChangeUpdate: {
    MyObj *obj = (MyObj *)anObject;
    if (obj.deletedValue) { // NOTE: deletedValue returns the deleted property as BOOL
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    } else {
      [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
      break;
    }
  }
Run Code Online (Sandbox Code Playgroud)

这个问题是我收到错误信息:

无效更新:第0节中的行数无效.更新(3)后现有部分中包含的行数必须等于更新前该部分中包含的行数(3),加上或减去数字从该部分插入或删除的行数(插入1个,删除2个).用户信息(null)

基本上它抱怨NSFetchedResultsController中的对象数量和表格中的单元格数量没有同步.

希望这更清楚:

// DB Items (Name, Deleted):
[Foo, NO]
[Bar, NO]
[Baz, NO]

// mark one as deleted
Objects[1].deletedValue = YES;

// DB items now look like so:
[Foo, NO]
[Bar, YES]
[Baz, NO]
Run Code Online (Sandbox Code Playgroud)

即使NSFetchedResultsController的NSFetchRequest的NSPredicate设置为deleted == NO,NSFetchedResultsController 仍然会看到3个项而不是2个.

我该如何解决这个问题?我需要以某种方式刷新NSFetchedReultsController吗?还有什么可能是问题?

Sen*_*ful 18

问题是我没有意识到deleted在这种情况下这是一个保留字.我不得不重命名这个领域,它运作良好.