草庐IT

ios - 应用程序每次从 "You have illegally mutated the NSFetchedResultsController' s 获取请求启动时突然崩溃”,但解决方案令人不安

coder 2023-09-23 原文

每次运行我的应用程序时,我都会突然收到以下错误:

CoreData: 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:

这是调用堆栈中的前十项:

*** First throw call stack:
(
    0   CoreFoundation                      0x04b835e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x022c68b6 objc_exception_throw + 44
    2   CoreData                            0x020a1b41 -[NSFetchedResultsController performFetch:] + 913
    3   Syllable                            0x00036aa9 -[RootViewController fetchedResultsController] + 777
    4   Syllable                            0x0003772b -[RootViewController tableView:numberOfRowsInSection:] + 91
    5   UIKit                               0x00d1d240 -[UISectionRowData refreshWithSection:tableView:tableViewRowData:] + 2510
    6   UIKit                               0x00d20b3d -[UITableViewRowData numberOfRows] + 98
    7   UIKit                               0x00ba94c2 -[UITableView noteNumberOfRowsChanged] + 120
    8   UIKit                               0x00ba8e6f -[UITableView reloadData] + 814
    9   UIKit                               0x10378ed1 -[UITableViewAccessibility(Accessibility) reloadData] + 50
    10  UIKit                               0x00bac8d3 -[UITableView _reloadDataIfNeeded] + 65

它提供的内容更多,但似乎都源于我发布的第一个错误。如果它们有帮助,请告诉我,我会发布它们。

不过这个问题真的很奇怪。它似乎无处不在。即使我使用 git 恢复到以前的工作版本它仍然崩溃,所以我不知道是什么原因造成的。

有一个 solution posted on Stackoverflow但这有点令人不安。将缓存设置为 nil 是否会从我的应用程序中删除缓存功能/使其变慢?会带来什么后果?

我正在对我的应用程序进行新的更新,首要任务是确保我的现有/ future 用户不会崩溃。


编辑:我相信这是导致问题的原因(尽管我已经删除它并且问题仍然存在):

我的 AppDelegate 中的 applicationDidFinishLaunching 中有以下代码,它基本上用于在应用程序首次启动时在 Core Data 中创建一个特殊对象。在添加这个之后,问题似乎就发生了,尽管此后不久就删除了代码。我现在不应该操纵核心数据吗(是不是太早了)?

// If it's the first time launching, create and add a sample article for an introduction
if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"IsFirstTimeLaunching"] isEqualToString:@"YES"]) {
    NSManagedObjectContext *context = self.managedObjectContext;

    Article *article = [NSEntityDescription insertNewObjectForEntityForName:@"Article" inManagedObjectContext:context];
    article.source = @"text";
    article.body = @"some text";
    article.timeStamp = [NSDate date];

    NSError *error;
    [context save:&error];

    [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"IsFirstTimeLaunching"];
}

我的 AppDelegate 中也有这个 block ,它已经存在了很长一段时间,但老实说,我不确定它到底做了什么,我可能刚刚写完它而忘记完成它......

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    NSManagedObjectContext *context = self.managedObjectContext;
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Article" inManagedObjectContext:context];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entity];    
}

最佳答案

您有以下选择:

  1. 将缓存设置为nil。如果您没有遇到性能问题,这实际上是可以的。如果获取需要很长时间,FRC 缓存确实可以大大提高速度。首先尝试这个解决方案。

  2. 设计一个具有不同缓存名称的方案。您的 FRC 可以确定在惰性实例化期间它必须执行哪个提取并使用适当的缓存名称。例如,如果您有一个搜索 Controller ,您可以使用范围按钮的状态。
    对于此解决方案(如果您只使用一个缓存名称),重要的是如果您更改了 FRC 的 ,则不要在获取的结果 Controller 上调用 performFetch提取请求。这正是导致这次崩溃的原因。相反,您可以将 FRC 设置为 nil 并让它懒惰地创建自己。

  3. 在适当的时候用deleteCacheWithName:删除缓存。

关于ios - 应用程序每次从 "You have illegally mutated the NSFetchedResultsController' s 获取请求启动时突然崩溃”,但解决方案令人不安,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19760296/

有关ios - 应用程序每次从 "You have illegally mutated the NSFetchedResultsController' s 获取请求启动时突然崩溃”,但解决方案令人不安的更多相关文章

随机推荐