【问题标题】:Changing NSFetchedResultsController's fetchRequest.predicate does not trigger delegate更改 NSFetchedResultsController 的 fetchRequest.predicate 不会触发委托
【发布时间】:2016-01-10 20:47:36
【问题描述】:

我在 FRC 的 fetchRequest 上有一个 NSPredicate。在某个时候,一个对象被添加到 CoreData,我创建了一个新谓词,更新 fetchRequest 并执行获取:

self.fetchedAddressesController.fetchRequest.predicate = self.predicate;
BOOL success = [self.fetchedAddressesController performFetch:nil];

但是,这不会调用像 controllerWillChangeContent: 这样的 FRC 委托方法。而且我的表格视图没有更新。

但是,当我添加以下行时:

[self.tableView reloadData];

在上面显示的两个下方,我确实看到了预期的更新。这说明要显示的数据确实发生了变化。

我检查了新的谓词,没问题。我还将FRC的delegate设置为self,其他情况下调用它的方法。

任何想法已经有什么问题了吗?

【问题讨论】:

    标签: ios objective-c nsfetchedresultscontroller nsfetchrequest


    【解决方案1】:

    您描述的行为是预期的。根据Apple documentation,如果要修改 NSFetchedResultsController 上的获取请求,则必须删除缓存(如果您正在使用缓存),修改 NSFetchRequest,然后调用 performFetch:(不会调用任何委托方法)。

    如果您想知道谓词之间发生了什么变化,您需要存储旧状态并进行比较。我过去为此使用的库是Doppelganger

    【讨论】:

    • 我确实查阅了这个文档,但我并没有轻易发现它说没有调用委托方法。我在哪里可以找到那个?相反,我读到:'仅内存跟踪:......更新部分和订购信息......'。
    • 参见developer.apple.com/library/ios/documentation/CoreData/…中的“修改获取请求”部分
    【解决方案2】:

    当 FRC 观察到在您执行提取后它所关注的已提取对象集发生变化时,将调用委托方法。如果您更改谓词并进行新的提取,FRC 将被重置,现在正在观察一组不同的对象。没有调用委托方法,因为原始对象集中没有任何变化。

    【讨论】:

      【解决方案3】:

      如果你真的要更改实体,请小心...

      我们遇到了一个棘手的问题,不仅排序发生了变化,而且实际的实体类也发生了变化,因此对于两个不同的选项卡按钮,

      let r = NSFetchRequest<NSFetchRequestResult>(entityName: "CD_Cats")
      

      然后..

      let r = NSFetchRequest<NSFetchRequestResult>(entityName: "CD_Dogs")
      

      事实上,如果你这样做,这将不起作用:

      func buttonLeft() {
          mode = .cats
          bringupFetchRequest()
          pull.feedForCats() // get fresh info if any at the endpoints
      }
      
      func buttonRight() {
          mode = .dogs
          bringupFetchRequest()
          pull.feedForDogs() // get fresh info if any at the endpoints
      }
      

      它最终会崩溃。

      看来你需要这个:

      func buttonLeft() {
          mode = .cats
          bringupFetchRequest()
          tableView.reloadData()
          pull.feedForCats() // get fresh info if any at the endpoints
      }
      
      func buttonRight() {
          mode = .dogs
          bringupFetchRequest()
          tableView.reloadData()
          pull.feedForDogs() // get fresh info if any at the endpoints
      }
      

      这(似乎)可靠地工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多