使用异步核心数据获取重复 viewcontroller push/pop 时应用程序崩溃 (EXC_BAD_ACCESS)

App crashes (EXC_BAD_ACCESS) on repeated viewcontroller push/pop with async core data fetch

我的应用程序因 EXC_BAD_ACCESS 错误而崩溃 :( 这几天一直让我头疼。当反复推送和弹出 UIViewController 而后者又执行异步 CoreData 获取时发生崩溃。之后a 一般会出现3-4次,简化的情况如下:

我有一个 UINavigationController 和一个 UIViewController 作为 rootController。这个 UIViewController 像这样进行推送:

UINavigationController *controller = [self.storyboard instantiateViewControllerWithIdentifier:@"List"]; // List is the StoryboardID of another UIViewController.
[self.navigationController pushViewController:controller animated:YES];

接下来,推送的 UIViewController 执行 NSAsynchronousFetchRequest,如下所示:

- (void)fetchData
{
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:self.entityName];
    fetchRequest.predicate = self.basePredicate;

    __weak typeof(self) weakSelf = self;

    // Initialize asynchronous fetch request.
    NSAsynchronousFetchRequest *asynchronousFetchRequest = [[NSAsynchronousFetchRequest alloc] initWithFetchRequest:fetchRequest completionBlock:^(NSAsynchronousFetchResult *result) {
        dispatch_async(dispatch_get_main_queue(), ^{
            weakSelf.fetchedItems = [NSSet setWithArray:result.finalResult];
        });
    }];

    // Execute asynchronous fetch request.
    [self.managedObjectContext performBlock:^{
        NSError *asynchronousFetchRequestError = nil;
        [weakSelf.managedObjectContext executeRequest:asynchronousFetchRequest error:&asynchronousFetchRequestError];

        if (asynchronousFetchRequestError) {
            DDLogError(@"Unable to execute asynchronous fetch result: %@, %@", asynchronousFetchRequestError, asynchronousFetchRequestError.localizedDescription);
        }
    }];
}

EXC_BAD_ACCESS 崩溃仅在将结果设置为 fetchedItems var 时发生。删除该行时它不会发生,所以我怀疑一定有问题。我已经用 "Enable Zombie Objects" 进行了测试,当我启用它时,应用程序不会崩溃,也不会给我任何额外的信息。

如有任何帮助,我们将不胜感激!

deanware 评论中的 link 以某种方式让我找到了解决方案。至少到目前为止,它现在似乎工作正常。我必须承认,核心数据和多线程对我来说仍然是一个很大的挑战trial/error。以下解决了我的问题,我希望有一天能完全理解为什么。

我替换了:

_managedObjectContext = [RKManagedObjectStore defaultStore].persistentStoreManagedObjectContext;

作者:

_managedObjectContext = [[RKManagedObjectStore defaultStore] newChildManagedObjectContextWithConcurrencyType:NSMainQueueConcurrencyType tracksChanges:YES];

(顺便说一句,我正在使用 RestKit)