NSOperationQueue添加后台线程操作

时间:2016-01-04 12:04:57

标签: ios objective-c multithreading nsoperationqueue nsthread

我正在尝试将后台线程操作添加到NSOperation队列并希望按序列执行,因此我将 setMaxConcurrentOperationCount 设置为1但无法实现同步过程。

我尝试使用以下代码,

 NSOperationQueue *queue = [NSOperationQueue new];
[queue setMaxConcurrentOperationCount:1];


    [queue addOperationWithBlock:^{

        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
            for (uint i=0; i<=9999999; i++) {
                NSLog(@"Loop A");
            }
        });
    }];

[queue addOperationWithBlock:^{

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
    for (uint i=0; i<=9999999; i++) {
        NSLog(@"Loop B");
    }
    });
}];

那将记录,

2016-01-04 17:25:41.861 TestOperation[582:111196] Loop B
2016-01-04 17:25:41.861 TestOperation[582:111194] Loop A
2016-01-04 17:25:41.864 TestOperation[582:111196] Loop B
2016-01-04 17:25:41.866 TestOperation[582:111194] Loop A
2016-01-04 17:25:41.867 TestOperation[582:111196] Loop B
2016-01-04 17:25:41.867 TestOperation[582:111194] Loop A
2016-01-04 17:25:41.868 TestOperation[582:111194] Loop A
2016-01-04 17:25:41.869 TestOperation[582:111194] Loop A

并希望此操作首先完成循环A,然后循环B.

3 个答案:

答案 0 :(得分:2)

你不应该使用dispatch_async。您已经使用操作队列将工作移至后台线程,因此您不需要使用dispatch_async再次移动。通过使用dispatch_async,您可以完成操作,然后您可以同时处理其他2个后台线程。

答案 1 :(得分:1)

你似乎对NSOperationBlock和dispatch_async完全感到困惑。 NSOperationBlock操作都调度到后台队列。调度接近零时间,然后NSOperationBlock完成,下一个NSOperationBlock运行。哪个调度另一个块。然后两个块都在不同的线程上运行,每个线程都记录。您的输出正是预期的结果。

如果你想要在另一个之后发生一件事,最简单的方法就是一个块在它完成之前调用另一个块。

答案 2 :(得分:0)

前一段时间我也遇到过类似的问题,但你似乎有所不同,但你可以使用我开发的这个课程

https://www.cocoacontrols.com/controls/sktaskmanager

您可以创建小任务并按顺序或同时执行该任务。

SKTask *aTask1=[SKTask taskWithBlock:^(id result, BlockTaskCompletion completion) {
        // your async task goes here i.e. image downloading in background

      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        for (uint i=0; i<=9999999; i++) {
            NSLog(@"Loop A");
        }
        // once task is completed call this block
        completion(nil); //this is important otherwise next task will not be exexute 
 });
}];


SKTask *aTask2=[SKTask taskWithBlock:^(id result, BlockTaskCompletion completion) {
    // your async task goes here i.e. image downloading in background
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        for (uint i=0; i<=9999999; i++) {
            NSLog(@"Loop B");
        }
        // once task is completed call this block
        completion(nil); //this is important otherwise next task will not be exexute 

    });
}];

创建所需数量的任务,并将所有任务添加到一个数组中 使用包含所有SKTask对象的数组调用此方法

[SKTaskManager sequenceOperations:arrTask completion:^{
    NSLog(@"all task completed");
}];

这将按顺序执行任务,一旦aTask1完成,然后aTask2将启动。

快乐编码