У меня есть функция, позволяющая просто называть ее «Функция обновления», которая отправляет RKManagedObjectRequestOperation на мой сервер для извлечения некоторых объектов. Я настроил эту операцию на автоматическое сохранениеToPersistentStore, а затем запустил ее. В обработчике завершения успеха «RKManagedObjectRequestOperation» я вызываю функцию, которая выполняет NSFetchRequest, чтобы получить обновленный список объектов, соответствующих определенным критериям, и передать этот массив и флаг BOOL, если в блоке завершения были новые данные.RestKit Сбой во время RKManagedObjectRequestOperation objc_msgSend
В обработчике завершения работы «Обновление функции» вызвать функцию под названием getUpdatedList, которая делает запрос NSFetchRequest так:
NSUInteger now = [[NSDate date] timeIntervalSince1970];
NSArray *predicates = @[
[NSPredicate predicateWithFormat:@"endAt > %d", now],
[NSPredicate predicateWithFormat:@"deleted != %@", @YES]
];
NSManagedObjectContext *managedObjectContext = [self managedObjectContext]; //(REMOVED: _objectManager.managedObjectStore.persistentStoreManagedObjectContext;)
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:predicates];
[fetchRequest setPredicate:compoundPredicate];
NSError *error = nil;
NSArray *fetchedRecords = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (sortDescriptor) {
fetchedRecords = [fetchedRecords sortedArrayUsingDescriptors:@[sortDescriptor]];
}
DDLogInfo(@"Retrieving list of %@ objects from local database - got %d results.", entityName, fetchedRecords.count);
return fetchedRecords;
- (NSManagedObjectContext *)managedObjectContext {
if (_globalContext != nil) {
return _globalContext;
}
NSPersistentStoreCoordinator *coordinator = _objectManager.managedObjectStore.persistentStoreCoordinator;
if (coordinator != nil) {
_globalContext = [[NSManagedObjectContext alloc] init];
[_globalContext setPersistentStoreCoordinator:coordinator];
}
return _globalContext;
}
Теперь, я никогда лично видел этот крах сам, так что я не знаю точно, что происходит, но в моих журналах я дошел до того, что в нем говорится: «Извлечение списка объектов% @ из локальной базы данных - получилось x результатов», а затем журнал начнется снова, что произойдет, когда сбой приложений. Где-то посреди этого RKManagedObjectRequestOperation и возвращения обновленного списка приложение вылетает как 1/1000 раз ...
Ниже приведена одна из трасс стека, полученная от Crashlytics. Существует ряд функций, которые вызывают функцию «Обновить», некоторые из фона, некоторые на переднем плане, но все трассировки стека ссылаются на эту «функцию обновления», которую вы видите в строке 9 ниже (updateAndFetchInfoWithCompletionHandler):
Thread : com.apple.uikit.backgroundTaskAssertionQueue
0 libsystem_kernel.dylib 0x38911a50 mach_msg_trap + 20
1 libsystem_kernel.dylib 0x3891184d mach_msg + 40
2 SpringBoardServices 0x34d2b42d SBGetBackgroundTimeRemaining + 52
3 SpringBoardServices 0x34d29461 SBSGetBackgroundTimeRemaining + 36
4 UIKit 0x30685b23 __40-[UIApplication backgroundTimeRemaining]_block_invoke + 10
5 libdispatch.dylib 0x38858d3f _dispatch_client_callout + 22
6 libdispatch.dylib 0x3885d6c3 _dispatch_barrier_sync_f_invoke + 26
7 UIKit 0x30685a97 -[UIApplication backgroundTimeRemaining] + 182
8 <redacted> 0x002345df __46-[LocationManager handleExitedRegion]_block_invoke_2 (LocationManager.m:262)
9 <redacted> 0x002451e3 __57-[DataManager updateAndFetchInfoWithCompletionHandler:]_block_invoke (DataManager.m:719)
10 <redacted> 0x00340d0d __66-[RKObjectRequestOperation setCompletionBlockWithSuccess:failure:]_block_invoke229 (RKObjectRequestOperation.m:506)
11 libdispatch.dylib 0x38858d53 _dispatch_call_block_and_release + 10
12 libdispatch.dylib 0x38858d3f _dispatch_client_callout + 22
13 libdispatch.dylib 0x3885b6c3 _dispatch_main_queue_callback_4CF + 278
14 CoreFoundation 0x2dba3681 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 8
15 CoreFoundation 0x2dba1f4d __CFRunLoopRun + 1308
16 CoreFoundation 0x2db0c769 CFRunLoopRunSpecific + 524
17 CoreFoundation 0x2db0c54b CFRunLoopRunInMode + 106
18 GraphicsServices 0x32a796d3 GSEventRunModal + 138
19 UIKit 0x3046b891 UIApplicationMain + 1136
20 <redacted> 0x000a3197 main (main.m:18)
есть ли что-то очевидно, что здесь я пропускаю это вызывает все эти сбои
EDIT:. изменил код выше, чтобы отразить другой контекст управляемого объекта после комментариев
Очень интересно. Является ли код, который выполняется внутри блоков успеха/отказа RKManagedObjectRequestOperation, выполняется в основном потоке? Если да, то это выполняется в основном потоке. Что вы говорите, мне нужно изменить управляемый объектОбъект, который я использую? Я точно не эксперт по Core Data. Спасибо за вашу помощь. – Mike
На самом деле, запуск операции напрямую не переключает нить. Но вы определенно не должны использовать постоянный контекст. Или если вы это сделаете, вы должны выполнить выборку внутри блока выполнения. – Wain
Мне только нужно получить 2 набора объектов из основных данных в моем приложении. Как мне создать и управлять контекстом? Могу ли я использовать тот, который я использую для обоих, или мне нужно создавать его каждый раз, когда я иду для извлечения объектов? – Mike