0

确定这里进入我的设置: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) 

应用程序设置:

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

  • 第一tableviewcontroller显示所有ShoppingItems
    • 它使用一个NSFetchedResultsController来检索数据
    • 此控制器的sortdescriptor被设置为 “Product.Category.Name”
    • 的sectionNameKeyPath被设定as“Product.Category.Name”
    • 没有谓词集
    • 缓存名称为此NSFRC设置
    • 这可以帮助我根据产品类别将购物商品分组到各个部分。
  • 第二tableviewcontroller显示所有产品
    • 它采用了NSFRC以及检索数据
    • Sortdescriptor - “Category.Name”
    • SectionNameKeyPath - “Category.Name”
    • 谓词集为“活动== 1” - 仅加载活动产品
    • 缓存名称也为此NSFRC设置
    • 这可以帮助我根据产品类别将产品分组。

场景:

  • 当我改变通过第三屏幕与产品相关联的类别,其中显示的产品适当地刷新本身,通过reslotting产品进入一不同的实现代码如下(和正确)部分
  • 但是在显示购物项目的桌面上没有发生同样的情况
  • 这不是我猜测的谓词的问题,因为问题不是关于丢失我tems,它更多的是关于插入错误部分的项目。

这两个tableviewcontrollers的设置方式都与NSFRCDelegate通知在更改段和行信息时一样。

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

P.S. :Am @ work,不能发布代码片段。可以回家做,如果这会有所帮助。

+0

莎拉,我敢肯定,与您的购物项目控制器相关联的NSFRC未被通知更改,可能是因为您使用的提取请求谓词不正确。至少,我们需要两个谓词来帮助你。 – 2010-08-30 07:36:57

+0

我已经在问题中包含了谓词信息Eric – Sara 2010-08-30 08:59:10

回答

0

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

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

如果ShoppingItems表及变化视图份额的上下文,然后在改变视做任何改动都会自动在ShoppingItems表中出现,但除非你合并范围内的变化,改变将不会出现在购物项目表。

如果几乎必须是单独的上下文,因为ShoppingItems只能通过遍历Product遍历关系才能获得其类别名称。如果ShoppingItems显示正确的类别,但Product必须表示每个表访问每个Product对象的不同版本。

+0

在整个应用程序中只有一个managedObjectContext - 我的AppDelegate公开的那个。有没有可能AppDelegate创建多个对象上下文,尽管我调用它上的相同属性来始终获取上下文? – Sara 2010-08-30 17:37:50

+0

不,如果您使用Xcode模板中的锅炉板代码,则不会有多个上下文。您可以通过记录每个视图控制器使用的上下文来检查重复的上下文,并查看它们是否都具有相同的地址。 – TechZen 2010-08-30 17:52:38

+0

顺便说一句,在阅读您的评论之前,我只是这样做了,并且两个控制器使用的objectContext都指向相同的对象(相同的地址) – Sara 2010-08-30 17:57:05

0

奇怪的问题,至少可以说。难道NSFetchedResultsController在使用多于两个级别的区段名称关键字路径时并未收到关于区段更改的通知?

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

名为“类别名称”只读属性添加到您的ShoppingItem类,有下面的实现:

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

然后,添加下面的方法来您的ShoppingItem实施:

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

这将确保每当类别的名称发生变化时,KVO系统将还会触发categoryName的更改通知,因此希望将NSFRC通知更改。当然,使用categoryName作为NSFRC的sectionNameKeyPath。

让我知道这是否工作。

+0

还没有运气埃里克。 我试着在头文件中加入你在实现文件中共享的代码片段,如下所示: @property(nonatomic,readonly,getter = categoryName)NSString * categoryName; 我在getter以及keyPathsForValues ...方法中都放置了断点。当吸气剂中的那个被击中结果中的每个项目时,另一个方法中的那个从未被击中。 我再次检查名称(包括大小写)是否与建议的一样。我甚至尝试将静态方法名称从... CategoryName更改为... categoryName,但仍然徒劳无功。 – Sara 2010-09-01 09:31:53

0

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