У меня есть следующий отчет аварии из моего выпущенном приложения:Ядра параллелизма данных `performBlockAndWait:` NSManagedObjectContext зомби
synchronizeMyWords
метод извлекает объекты из базы данных, создает контекст собственной очереди с основным контекстом родителем и, наконец, сохраняет результаты. Все операции находятся в фоновом потоке. Этот метод вызывается каждый раз, когда приложение переходит в background
и foreground
. Вот упрощенный метод:
- (AWSTask *)synchronizeMyWords {
__weak typeof(self) weakSelf = self;
AWSContinuationBlock block = ^id _Nullable(AWSTask * _Nonnull task) {
if ([task.result isKindOfClass:[NSArray class]]) {
NSArray * records = (NSArray *)task.result;
NSManagedObjectContext * context = [NSManagedObjectContext MR_contextWithParent:[NSManagedObjectContext MR_defaultContext]];
[context performBlockAndWait:^{
for (NSDictionary * info in records) {
[RDRWord MR_createEntityInContext:context];
}
[context save:nil];
}];
return [AWSTask taskWithResult:@YES];
}
return [AWSTask taskWithError:[NSError errorWithDomain:@"" code:404 userInfo:nil]];
};
AWSExecutor * executor = [AWSExecutor defaultExecutor];
return [[self loadLocalWords] continueWithExecutor:executor withBlock:block];
}
Как вы видите, я использую Magical Record 3rd библиотеку партии управлять стеком Core Data. Вот метод создания контекста собственной очереди:
+ (NSManagedObjectContext *) MR_contextWithParent:(NSManagedObjectContext *)parentContext
{
NSManagedObjectContext *context = [self MR_newPrivateQueueContext];
[context setParentContext:parentContext];
[context MR_obtainPermanentIDsBeforeSaving];
return context;
}
Вы можете проверить всю NSManagedObjectContext+MagicalRecord
категории на GitHub here.
Как доступно, что context
объект внутри performBlockAndWait:
выпущен до того, как он выходит из области? Я лично не могу воспроизвести авария, но многие мои пользователи (устройства IOS 8.1 - 10) затронуты этой проблемой.
UPDATE 1:
Вот, например, тот же доклад на blog
Исправлен основной контекст не сохраняется; основной контекст сохраняется, когда приложение переходит в фоновый режим. Это отдельная операция. 'continueWithExecutor: block:' означает, что 'continuationBlock' работает в фоновом потоке. Задачей здесь является [BFTask] (https://github.com/BoltsFramework/Bolts-ObjC) подкласс, через краткое описание ссылки. –