Macos 核心数据并发:两个独立于主线程的连续大任务(其中一个大任务需要多个并发任务)
我有预配置文件(带有许多参数),我将其值保存在CoreData中。 让我们称之为第一项任务:Macos 核心数据并发:两个独立于主线程的连续大任务(其中一个大任务需要多个并发任务),macos,core-data,concurrency,objective-c-blocks,grand-central-dispatch,Macos,Core Data,Concurrency,Objective C Blocks,Grand Central Dispatch,我有预配置文件(带有许多参数),我将其值保存在CoreData中。 让我们称之为第一项任务: Create new instance of NSManagedObjectContext: NSManagedObjectContextVariable. [parametersInFileArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBloc
Create new instance of NSManagedObjectContext: NSManagedObjectContextVariable.
[parametersInFileArray enumerateObjectsWithOptions:NSEnumerationConcurrent
usingBlock:^(id obj, NSUInteger idx, BOOL *stop){
[NSManagedObjectContextVariable performBlock:^{
bla-bla-bla
insertNewObjectForEntityForName:entityName1 inManagedObjectContext:NSManagedObjectContextVariable;
[NSManagedObjectContextVariable save:&error];
}
}
然后,我想并发处理每个值(存储在CoreData中较早的值),并将其保存到CoreData(entityName2与entityName1的关系为1到任意)。让我们称之为第二项任务:
1.Create new instance of NSManagedObjectContext.
2.Get (NSArray *)fetchedObjects form entity("entityName1")
3.
[fetchedObjects enumerateObjectsUsingBlock:^(entityName1Class *obj, NSUInteger idx, BOOL *stop){
NSArray* newParameters = getManyNewParametersForObj(obj);
[newParameters enumerateObjectsUsingBlock:^(Parameter *param, NSUInteger idx, BOOL *stop)
{
bla-bla-bla
insertNewObjectForEntityForName:entityName2 inManagedObjectContext:NSManagedObjectContextVariable;
[NSManagedObjectContextVariable save:&error];
}
}
所以。我需要依次执行任务1和任务2。并与主线程分离。在第一个任务未完成之前,第二个任务无法启动
在任务2中,我需要从fetchedObjects(Obj)并发中为每个元素启动GetManyNewParametersForbj+insertNewObjectForEntityForName+save。这是一个很长的操作(从网络获取参数),它们彼此不依赖
在任务1和任务2中的每次保存中,我都会更新NSTableView(注意NSManagedObjectContextDidSaveNotification)
我对dispatch_apply、performBlock、EnumerateObjectsSusingBlock、EnumerateObjectsSusingBlock、EnumerateObjectsSwithOptions感到非常困惑:NSEnumerationConcurrent、semaphoreWait、semaphoreBlock、blockUntilWait、serialQueue、parallelQueue等
建议我如何做我需要的事。
谢谢。你看过和吗
MagicalRecord可以帮助创建上下文、保存在块(其他线程)中以及合并回父上下文
因此,设置上下文和线程成为
[MagicalRecord saveWithBlock:^(NSManagedObjectContext*localContext)
该块将使用自己的上下文在自己的线程上执行。此外,您可以定义一个将在主线程上执行的完成块。这样,您可以在后台线程和主线程之间获得反馈。并且避免使用信号量
SMC是一个针对Objective C和其他语言的有限状态机编译器。理解它们的语法和实现FSM的方式可能需要一点时间,但它绝对值得前期的努力。一旦实现,维护和更改将变得非常容易。已经生成了一个很棒的教程PDF
使用SMC,为每个任务定义一个状态
。每个状态将有一个输入操作
。输入操作
将是包含您在问题中显示的代码的方法
在状态1
结束或调用它任务1
时,您触发转换
到下一个状态。FSM将切换并执行下一个定义状态的输入操作,比如任务2
。这样任务1
在任务2
之前执行
FSM不支持开箱即用的并行子任务。如果要并行运行超级任务2的子任务,则需要监视每个子任务的完成情况。我使用三个计数器来完成此操作
it表示启动的子任务总数totalTasks
在子任务完成且无错误时递增goodTasks
- 当子任务遇到问题时,
将递增failedTasks
goodTasks+failedTasks==totalTasks
时,超级任务2的所有子任务都已完成。如果failedTasks==0
则所有任务都进行得很顺利。
例如,failedTask
会使FSM切换到错误处理状态
还有其他的有限状态机实现,但我发现SMC非常灵活