2014-04-25 2 views
0

У меня есть функция, позволяющая просто называть ее «Функция обновления», которая отправляет 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:. изменил код выше, чтобы отразить другой контекст управляемого объекта после комментариев

ответ

1

Вы не должны используйте persistentStoreManagedObjectContext. Если этот код работает в основном потоке, вы должны использовать май n контекст очереди. Если вы работаете на произвольном фоновом потоке, вы должны создать новый контекст специально для этого вызова.

Контексты являются конкретными потоками, и вы должны уважать право собственности на каждый создаваемый вами контекст.

При работе на фоновом потоке создайте новый контекст с помощью newChildManagedObjectContextWithConcurrencyType:tracksChanges:. Это поддерживает ограничения потоков, требуемые контекстом.

+0

Очень интересно. Является ли код, который выполняется внутри блоков успеха/отказа RKManagedObjectRequestOperation, выполняется в основном потоке? Если да, то это выполняется в основном потоке. Что вы говорите, мне нужно изменить управляемый объектОбъект, который я использую? Я точно не эксперт по Core Data. Спасибо за вашу помощь. – Mike

+0

На самом деле, запуск операции напрямую не переключает нить. Но вы определенно не должны использовать постоянный контекст. Или если вы это сделаете, вы должны выполнить выборку внутри блока выполнения. – Wain

+0

Мне только нужно получить 2 набора объектов из основных данных в моем приложении. Как мне создать и управлять контекстом? Могу ли я использовать тот, который я использую для обоих, или мне нужно создавать его каждый раз, когда я иду для извлечения объектов? – Mike

Смежные вопросы