NSFetchedResultsController, отказывающий на performFetch: при использовании кэша

Я использую 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;
}

Это сообщения, которые я получаю когда сбои приложения:

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

У меня действительно нет подсказки относительно того, почему это говорит, что, поскольку я не полагаю, что делаю что-либо специальное, которое вызвало бы это. Единственной потенциальной проблемой является заголовок раздела (день), который я создаю как это при создании нового объекта:

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

// Set the day of the event
[event setValue:[formatter stringFromDate:[event valueForKey:@"utc_start"]] forKey:@"day"];

Как я упомянул, все это хорошо работает, если нет никакого включенного кэша. Любая справка ценится!

47
задан Oliver 25 April 2010 в 20:09
поделиться

5 ответов

Если вы используете симулятор, попробуйте сбросить его - я думаю, вы изменили карту объекта, и она запуталась из-за остатков кеша . Если нет, вы можете попробовать сделать то, что написано в сообщении об ошибке:

- (void)applicationWillTerminate:(UIApplication *)application {
    [NSFetchedResultsController deleteCacheNamed:@"Events"];
    //etc
}
3
ответ дан 26 November 2019 в 19:22
поделиться

Вы выходите из симулятора, используя кнопку «Домой» или завершая работу приложения в Xcode? Возможно, приложение не успевает закончить запись в кеш. Попробуйте использовать кнопку «Домой», чтобы выйти из приложения.

1
ответ дан 26 November 2019 в 19:22
поделиться

Если много классов реализуют один и тот же метод - (NSFetchedResultsController *)results, используете ли вы для каждого из них свой кэш? У меня была такая же проблема, и я думаю, что решил ее, используя разные имена кэша для некоторых классов, поскольку у меня разные NSPredicates.

1
ответ дан 26 November 2019 в 19:22
поделиться

У меня была аналогичная проблема с одним из моих приложений, когда Apple выпустила новую iOS 4.0. Найдите:

fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:nil];

И установите значение параметра cacheName равным нулю. У меня это сработало, надеюсь, сработает и для вас. Дай мне знать.

65
ответ дан 26 November 2019 в 19:22
поделиться

Я начал получать ту же ошибку, когда обновил MacBook Pro до Snow Leopard 10.6.4 и последней версии SDK.

Как выяснилось, многие из нас использовали код, который не соответствовал правилам, но мы не знали об этом, потому что CoreData на самом деле вела себя не в соответствии со своими правилами.

В частности, когда вы получаете данные, они попадают в кэш, а в версии 4.0 этот кэш не очищается автоматически в тех случаях, когда он очищался в более ранней версии SDK.

Для меня решение было простым. Я просто использовал метод класса, который очищает кэш. Вы можете указать отдельную сущность, но я указал nil, так что он просто делает их все в этом конкретном фрагменте кода запуска:

[NSFetchedResultsController deleteCacheWithName:nil];

Внезапно, маленькое приложение, над которым я работал только для ознакомления с CoreData, снова работает.

30
ответ дан 26 November 2019 в 19:22
поделиться