使用异步核心数据获取重复 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)
我的应用程序因 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)