— это процесс синхронизации, который должен выполняться в фоновом режиме с использованием AFNetworking и Magical Record, но вызывает постоянное зависание, когда контроллер представления, подключенный к NSFetchedResultsController, в данный момент открыт или был открыт (, но выскочил ).
Приложение синхронизируется при первом открытии телефона пользователем, а затем всегда использует данные в хранилище сохраняемости Core Data через структуру Magical Record. Затем, когда пользователь хочет убедиться, что данные являются самой последней версией, он заходит в настройки и нажимает «Re -Sync», что приводит к выполнению следующего кода:
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];
)И FRC установлен на ноль в ViewDidUnload-процесс фоновой синхронизации зависает из-за того, что FRC получает обновления контекста (, как и в случае 2 ). [PS :после зависания на несколько минут я закрываю отладчик, и он выдает мне SIGKILL на следующий код, поэтому я предполагаю, что FRC получает обновления контекста, что приводит к зависанию:
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
UITableView *tableView = controller == self.fetchedResultsController ? self.tableView : self.searchDisplayController.searchResultsTableView;
[tableView endUpdates]; <---- SIGKILL
}
Спасибо, надеюсь, я был достаточно подробным в своем вопросе.