是一个同步过程,应该在后台使用AFNetworking和Magical Record完成,但当连接到NSFetchedResultsController的视图控制器当前打开或已打开(但弹出)时会导致永久挂起。
应用程序会在用户第一次打开手机时同步,然后通过Magical Record框架始终在Core Data持久性存储中使用数据。然后,当用户想要确保数据是最新版本时,他们会进入设置并单击“重新同步”,这将导致执行以下代码:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
[[CoreDataOperator sharedOperator] commenceSync:self];
});
这会使用单例CoreDataOperator(NSObject的子类 - 也许它应该是NSOperation?)启动同步过程,它会触发以下代码:
[[ApiClient sharedClient] getDataRequest];
然后在单身AFHTTPClient子类中触发这个坏男孩:
[[ApiClient sharedClient] postPath:url parameters:dict
success:^(AFHTTPRequestOperation *operation, id responseObject) {
[request.sender performSelector:request.succeeded withObject:response];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[request.sender performSelector:request.failed withObject:response];
}
];
有效地说:AFHTTPClient发布此信息,当它成功时,将信息传回给提供的选择器(我知道这是通用的,但请求不是问题)
现在,对AFNetworking进行编码,以便在主线程上调用所有完成选择器(在本例中具体为成功和失败);所以为了防止阻塞主线程,处理响应并准备保存的代码被发送回后台线程:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
id responseData;
[self clearAndSaveGetData:responseData];
});
然后使用Magical Record框架(仍在后台线程中)调用导致保存的函数:
NSManagedObjectContext *localContext = [NSManagedObjectContext contextForCurrentThread];
[DATAENTITY truncateAllInContext:localContext];
<!--- PROCESS DATA INTO DATAENTITY -->
[localContext saveNestedContexts];
我选择了saveNestedContexts
,因为我在后台工作,我希望它一直推到默认上下文,我假设它是父上下文? (但到目前为止这还不成问题。)
现在,这些数据可能会成千上万行,因此我使用NSFetchedResultsController安全有效地访问这些数据,并且它们用于与设置或主页不同的视图控制器中。
[self.navigationController popViewControllerAnimated:YES];
)并且在ViewDidUnload中将FRC设置为nil - 后台同步过程 HANGS 由于看似FRC接收上下文更新(就像案例2一样)。[PS:挂了几分钟之后,我终止了调试器,它给了我一个SIGKILL以下代码,这就是为什么我认为FRC正在接收导致它挂起的上下文更新:
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
UITableView *tableView = controller == self.fetchedResultsController ? self.tableView : self.searchDisplayController.searchResultsTableView;
[tableView endUpdates]; <---- SIGKILL
}
谢谢,希望我在问题中足够详细。
答案 0 :(得分:1)
我知道这个问题很老但是因为这是MagicalRecord的常见问题,所以以下内容可能对某些人有帮助。
问题是由FRC的fetchRequest
和保存操作相互死锁引起的。以下为我解决了这个问题:
更新到最新的MagicalRecord版本(撰写本文时为2.1)。
然后使用以下内容完成所有后台保存:
MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
// create new objects, update existing objects. make sure you're only
// accessing objects inside localContext
[myObjectFromOutsideTheBlock MR_inContext:localContext]; //is your friend
}
completion:^(BOOL success, NSError *error) {
// this gets called in the main queue. safe to update UI.
}];