NSFetchedResultsController在performFetch上崩溃:使用缓存时

Oli*_*ver 47 iphone core-data objective-c nsfetchedresultscontroller

我使用NSFetchedResultsController来显示一堆对象,这些对象使用日期进行分区.在全新安装中,它完全正常工作,对象显示在表格视图中.然而,似乎当应用程序重新启动时,我遇到了崩溃.我在初始化NSFetchedResultsController时指定了一个缓存,当我不这样做时,它完美地工作.

以下是我创建NSFetchedResultsController的方法:

- (NSFetchedResultsController *)results {
    // If we are not nil, stop here
    if (results != nil)
        return results;

    // Create the fetch request, entity and sort descriptors
    NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:self.managedObjectContext];
    NSSortDescriptor *descriptor = [[NSSortDescriptor alloc] initWithKey:@"utc_start" ascending:YES];
    NSArray *descriptors = [[NSArray alloc] initWithObjects:descriptor, nil];

    // Set properties on the fetch
    [fetch setEntity:entity];
    [fetch setSortDescriptors:descriptors];

    // Create a fresh fetched results controller
    NSFetchedResultsController *fetched = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"day" cacheName:@"Events"];
    fetched.delegate = self;
    self.results = fetched;

    // Release objects and return our controller
    [fetched release];
    [fetch release];
    [descriptor release];
    [descriptors release];
    return results;
}
Run Code Online (Sandbox Code Playgroud)

这些是应用程序崩溃时收到的消息:

FATAL ERROR: The persistent cache of section information does not match the current configuration.  You have illegally mutated the NSFetchedResultsController's fetch request, its predicate, or its sort descriptor without either disabling caching or using +deleteCacheWithName:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'FATAL ERROR: The persistent cache of section information does not match the current configuration.  You have illegally mutated the NSFetchedResultsController's fetch request, its predicate, or its sort descriptor without either disabling caching or using +deleteCacheWithName:'
Run Code Online (Sandbox Code Playgroud)

我真的不知道为什么会这样说,因为我不相信我会做任何会造成这种情况的特殊事情.唯一可能的问题是节头(日),我在创建新对象时这样构造:

// Set the new format
[formatter setDateFormat:@"dd MMMM"];

// Set the day of the event
[event setValue:[formatter stringFromDate:[event valueForKey:@"utc_start"]] forKey:@"day"];
Run Code Online (Sandbox Code Playgroud)

就像我提到的,如果没有涉及缓存,所有这些都可以正常工作.任何帮助赞赏!

Iss*_*mTP 65

当Apple发布新的iOS 4.0时,我的一个应用程序遇到了类似的问题.搜索:

fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:nil];
Run Code Online (Sandbox Code Playgroud)

并将参数cacheName的值设置为nil.它对我有用,希望它能为你服务.让我知道.

  • 我不相信将缓存设置为nil是最佳答案.我们不是只是禁用所有缓存,放弃性能吗? (3认同)

小智 30

当我通过MacBook Pro升级到Snow Leopard 10.6.4和最新的SDK时,我开始遇到同样的错误.

事实证明,我们中的许多人一直在使用不符合规则的代码,但我们不知道它,因为CoreData并没有按照自己的规则行事.

具体来说,当您获取内容时,它们会被缓存,而在4.0中,如果在早期SDK中清除该缓存,则不会自动清除该缓存.

对我来说,解决方案很简单.我刚刚使用了清除缓存的类方法.你可以指定一个单独的实体,但是我指定了nil,所以它只是在这个特定的启动代码中完成它们:

[NSFetchedResultsController deleteCacheWithName:nil];
Run Code Online (Sandbox Code Playgroud)

突然之间,我所做的只是让我自己熟悉CoreData的小应用程序正在重新开始工作.


Mar*_*ams 15

直接从文档NSFetchedResultsController:

修改获取请求

您不能简单地更改获取请求以修改结果.如果要更改提取请求,则必须:

  1. 如果您使用缓存,请将其删除(使用deleteCacheWithName:).通常,如果要更改提取请求,则不应使用缓存.

  2. 更改提取请求.

  3. 调用performFetch:.


Ter*_*Tan 6

我遇到了类似的问题.当我检查调试器控制台时,它显示了缓存对象和获取的对象是什么,以便我可以找出它们不一致的原因.在我的情况下,这是由于不同的谓词.

由于我的谓词中的值不是动态的,因此我可以为每个谓词指定不同的缓存名称.这将为我指定的每个"类型"创建一个缓存.

我想你必须评估你需要缓存.指定nil表示在每次调用中都进行提取.

我发现只有当获取请求有一些变化时才会发生错误.如果要创建新的NSFetchRequest或更改谓词OR排序描述符,则应删除缓存或使用其他缓存.否则,请确保您具有相同的NSFetchRequest或确保保留NSFetchedResultsController,这应该可以解决您的问题.


sho*_*sti 3

如果您正在使用模拟器,请尝试重置它 - 我猜您已经更改了实体映射,并且它被剩余的缓存弄糊涂了。如果没有,您可以尝试按照错误提示执行操作:

- (void)applicationWillTerminate:(UIApplication *)application {
    [NSFetchedResultsController deleteCacheNamed:@"Events"];
    //etc
}
Run Code Online (Sandbox Code Playgroud)

  • 删除应用程序只会导致相同的循环。在终止时删除缓存难道不会完全破坏缓存的目的吗? (2认同)