NSFetchedResultsController ~ 缓存导致问题?
好的,这是我的设置:
对象模型:
* 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
缓存可能会导致暂时的问题,但如果您对上下文进行更改,缓存应该会自动刷新。您可以通过删除视图控制器的
viewWillAppear
方法中的 FRC 缓存来测试此问题。这样,当您返回视图时,它每次都会以新的缓存开始。我认为您更有可能有两个不同的托管对象上下文。您有一个用于
Product
表的上下文,另一个由Change-view
和ShoppingItems
表共享的上下文。如果
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 theChange-view
andShoppingItems
table.If the
ShoppingItems
table and the change-view share a context, then any alterations done in the change-view will appear automatically in theShoppingItems
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 theProduct
. IfShoppingItems
shows the correct category butProduct
that must mean that each table is accessing different versions of eachProduct
object.至少可以说,这是一个奇怪的问题。当使用超过 2 级的节名称键路径时,NSFetchedResultsController 是否不会收到节更改的通知?
您可以尝试以下解决方法来检查这一点:
将名为“categoryName”的只读属性添加到您的 ShoppingItem 类,并使用以下实现:
然后,将以下方法添加到您的 ShoppingItem 实现:
这将确保每次类别名称如果发生更改,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 :
Then, add the following method to your ShoppingItem implementation :
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.
尝试对不同的配置(即不同的排序或谓词)使用不同的缓存名称 - 它应该能够返回正确的数据。它对我有用。
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.