Macos 核心数据并发:两个独立于主线程的连续大任务(其中一个大任务需要多个并发任务)

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

我有预配置文件(带有许多参数),我将其值保存在CoreData中。 让我们称之为第一项任务:

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的子任务,则需要监视每个子任务的完成情况。我使用三个计数器来完成此操作

  • totalTasks
    it表示启动的子任务总数
  • goodTasks
    在子任务完成且无错误时递增
  • 当子任务遇到问题时,
    failedTasks
    将递增
现在,当
goodTasks+failedTasks==totalTasks
时,超级任务2的所有子任务都已完成。如果
failedTasks==0
则所有任务都进行得很顺利。 例如,
failedTask
会使FSM切换到错误处理状态

还有其他的有限状态机实现,但我发现SMC非常灵活