NSFetchedResultsController ~ 缓存导致问题?

发布于 2024-09-17 08:42:18 字数 1129 浏览 5 评论 0原文

好的,这是我的设置:

对象模型:

* Category object is at the root  
* Product is linked to a Category (many-to-1)
* ShoppingItem is linked to a Product (many-to-1)

应用程序设置:

我的应用程序在根目录中有一个 TabBarController,在每个选项卡的根目录中有一个 tableviewcontroller。

  • 第一个 tableviewcontroller 显示所有 ShoppingItems
    • 它使用 NSFetchedResultsController 来检索数据
    • 此控制器的排序描述符设置为“Product.Category.Name”
    • sectionNameKeyPath 设置为“Product.Category.Name”
    • 没有设置谓词
    • 为此 NSFRC 设置缓存名称
    • 这有助于我根据产品类别将购物商品分组。
  • 第二个 tableviewcontroller 显示所有产品
    • 它还使用 NSFRC 来检索数据
    • 排序描述符 --“类别.名称”
    • SectionNameKeyPath --“类别.名称”
    • 谓词集为“Active == 1” - 仅加载活动产品
    • 也为此 NSFRC 设置缓存名称
    • 这有助于我根据产品类别将产品分组。

场景:

  • 当我通过第三个屏幕更改与产品关联的类别时,显示产品的表格视图会通过将产品重新分配到不同的(且正确的)部分来适当地刷新自身,
  • 但显示产品的表格视图上不会发生同样的情况购物物品
  • 我猜这不是谓词的问题,因为问题不在于丢失物品,而更多在于放置在错误部分的物品。

两个 tableviewcontroller 的设置方式相同,当节和行信息发生更改时,NSFRCDelegate 会通知它们。

关于这里发生的事情有任何线索吗?这种行为正确吗?

PS:我正在工作,无法发布代码片段。如果有帮助的话,可以回家做。

Ok here goes my setup:

Object Model:

* Category object is at the root  
* Product is linked to a Category (many-to-1)
* ShoppingItem is linked to a Product (many-to-1)

Application setup:

My application has a TabBarController at the root and a tableviewcontroller at the root of each of the tabs.

  • The first tableviewcontroller shows all ShoppingItems
    • It uses a NSFetchedResultsController to retrieve the data
    • The sortdescriptor for this controller is set as "Product.Category.Name"
    • The sectionNameKeyPath is set as "Product.Category.Name"
    • There's no predicate set
    • Cache name is set for this NSFRC
    • This helps me group the shopping items based on its product categories into sections.
  • The second tableviewcontroller shows all Products
    • It uses a NSFRC as well to retrieve the data
    • Sortdescriptor -- "Category.Name"
    • SectionNameKeyPath -- "Category.Name"
    • The predicate set is "Active == 1" - to load only active products
    • Cache name is set for this NSFRC as well
    • This helps me group the products based on its categories into sections.

Scenario:

  • When I change the category associated with a product through a third screen, the tableview which displays products refreshes itself appropriately, by reslotting the product into a different (and correct) section
  • But the same isn't happening on the tableview which displays the shopping items
  • It is not an issue with the predicates I guess, as the problem is not about missing items, it is more about the items slotted in the wrong section.

Both the tableviewcontrollers are setup the same way to be notified by the NSFRCDelegate when changes to section and row info happen.

Any clues as to what's happening here? Is this behaviour correct?

P.S. : Am @ work and not able to post code snippets. Can go home and do it, if that would help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

枯寂 2024-09-24 08:42:18

缓存可能会导致暂时的问题,但如果您对上下文进行更改,缓存应该会自动刷新。您可以通过删除视图控制器的 viewWillAppear 方法中的 FRC 缓存来测试此问题。这样,当您返回视图时,它每次都会以新的缓存开始。

我认为您更有可能有两个不同的托管对象上下文。您有一个用于 Product 表的上下文,另一个由 Change-viewShoppingItems 表共享的上下文。

如果 ShoppingItems 表和更改视图共享上下文,则在更改视图中所做的任何更改都将自动显示在 ShoppingItems 表中,但更改不会出现在购物项目表,除非您合并上下文的更改。

如果几乎必须是单独的上下文,因为 ShoppingItems 只能通过遍历 Product 之间的关系来获取其类别名称。如果 ShoppingItems 显示正确的类别,但 Product 显示正确,则一定意味着每个表正在访问每个 Product 对象的不同版本。

Caching could cause a temporary problem but if you make changes to the context, the cache should be refreshed automatically. You can test for this problem by deleting the FRC cache in the view controller's viewWillAppear method. That way when you come back to the view it starts with a fresh cache every time.

I think it more likely that you have two different managed object context. You have one context for the Product table and another shared by the Change-view and ShoppingItems table.

If the ShoppingItems table and the change-view share a context, then any alterations done in the change-view will appear automatically in the ShoppingItems table but the alterations will not appear in Shopping Items table unless you merge the context's changes.

If pretty much has to be separate context because the ShoppingItems can only get its category name by walking the relationship across the Product. If ShoppingItems shows the correct category but Product that must mean that each table is accessing different versions of each Product object.

匿名。 2024-09-24 08:42:18

至少可以说,这是一个奇怪的问题。当使用超过 2 级的节名称键路径时,NSFetchedResultsController 是否不会收到节更改的通知?

您可以尝试以下解决方法来检查这一点:

将名为“categoryName”的只读属性添加到您的 ShoppingItem 类,并使用以下实现:

- (NSString *)categoryName {
    return self.Product.Category.Name;
}

然后,将以下方法添加到您的 ShoppingItem 实现:

+ (NSSet *)keyPathsForValuesAffectingCategoryName {
   return [NSSet setWithObjects:@"Product.Category.Name", nil];
}

这将确保每次类别名称如果发生更改,KVO 系统也会触发类别名称的更改通知,从而有望让 NSFRC 收到更改通知。当然,使用categoryName作为您的NSFRC的sectionNameKeyPath。

让我知道这是否有效。

Strange problem, to say the least. Could it be that NSFetchedResultsController doesn't get notified of changes to section when using a section name key path of more than 2 levels ?

You could try the following workaround to check this point :

Add a readonly property named "categoryName" to your ShoppingItem class, with following implementation :

- (NSString *)categoryName {
    return self.Product.Category.Name;
}

Then, add the following method to your ShoppingItem implementation :

+ (NSSet *)keyPathsForValuesAffectingCategoryName {
   return [NSSet setWithObjects:@"Product.Category.Name", nil];
}

This will ensure that each time the name of the category changes, the KVO system will also trigger a change notification for categoryName, thus hopefully getting the NSFRC notified of the change. Of course, use categoryName as the sectionNameKeyPath of your NSFRC.

Let me know if this works.

乖乖哒 2024-09-24 08:42:18

尝试对不同的配置(即不同的排序或谓词)使用不同的缓存名称 - 它应该能够返回正确的数据。它对我有用。

try using different cache names for different configuration (i.e, different sort or predicate) - it should be able to return correct data. It worked from me.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文