Мне было интересно, может ли кто-нибудь указать мне в правильном направлении, правильно ли я использую параллелизм. Я нахожу, что в настоящее время код очень громоздкий и почти неинтуитивный. В целях моей демонстрации обратите внимание на то, что архитектура CoreData описана Маркусом Заррой в его статье http://martiancraft.com/blog/2015/03/core-data-stack/. Поскольку операция может занять очень много времени, я хочу, чтобы весь этот процесс выполнялся в фоновом потоке.Я приближаюсь к параллелизму?
NSManagedContext *context = [[NSManagedContext alloc] initWithConcurrency:NSPrivateConcurrencyQueue];
context.parentContext = [[CoreDataController sharedDispatch] managedObjectContext];
[context performBlock: ^{
NSManagedObject *someManagedObject = [[context executeFetchRequest:request error:nil] firstObject];
NSString *resultFromLongOperation = [self someLongOperation:someManagedObject];
[self doSomething];
BOOL anotherResultFromLongOperation = [self aDifferentLongOperation:someManagedObject];
}];
Так из этого краткого примера, мы можем видеть, что я манипулируя переменной someManagedObject, которая имеет тип NSManagedObject и, следовательно, должны быть использованы в performBlock/performBlockAndWait, как это предписано Apple. Должен ли я проходить в контексте в someLongOperation и aDifferentLongOperation? Если я этого не сделаю, не означает ли это, что мне нужно будет создать еще один дочерний контекст и выполнить все функции, выполняемые внутри executeBlock/performBlockAndWait, и вернуть результат с типом __block? Как насчет того, если результат someLongOperation влияет на реакцию aDifferentLongOperation? Я все еще правильно структурирую свой код для такой ситуации?
Большое спасибо за продвинутый!
Этот вид кода, безусловно, уродливый, но он плотный. Другим подходом было бы использование GCD, что имеет смысл, если у вас много сложных вещей, работающих бок о бок. –
GCD все равно отправит отдельный поток, тем самым нарушив одно правило контекста/потока, установленное Apple. Однако, даже если это было разрешено, как это решает мою проблему? Мне нужно было бы использовать типы переменных __block для получения ответа? –
Вы можете создать очередную очередь и иметь один контекст для этой очереди. Чтобы безопасно связываться между потоками, вы передаете идентификаторы. Таким образом, поток 1 выполняет операцию поиска, находит три объекта, эти объекты нельзя безопасно использовать в другом потоке, но вы можете безопасно передавать их идентификаторы. – gnasher729