5

我有许多需要串行执行的任务,但任务包括完成块中的下一个块。

什么是一次完成这些任务的好技术,在当前任务完成其完成块后开始下一个任务?

除了具有串行 NSOperationQueue 的 NSOperation 子类之外,还有其他技术吗?

4

3 回答 3

7

标准解决方案:

  1. NSOperationQueue与. maxConcurrentOperationCount_ 1你说你不想那样做,但你没有说为什么。串行队列是最合乎逻辑的解决方案。

    例如:

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    queue.maxConcurrentOperationCount = 1;
    
    [queue addOperationWithBlock:^{
        NSLog(@"Starting #1");
        sleep(3);
        NSLog(@"Finishing #1");
    }];
    
    [queue addOperationWithBlock:^{
        NSLog(@"Starting #2");
        sleep(3);
        NSLog(@"Finishing #2");
    }];
    
    [queue addOperationWithBlock:^{
        NSLog(@"Starting #3");
        sleep(3);
        NSLog(@"Finishing #3");
    }];
    
  2. 如果您不想要 serial NSOperationQueue,您可以使用标准并发队列,但只需使每个操作都依赖于前一个操作。您将在不使用串行队列的情况下实现您正在寻找的串行行为。

    例如:

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    NSOperation *operation;
    NSOperation *previousOperation;
    
    operation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"Starting #1");
        sleep(3);
        NSLog(@"Finishing #1");
    }];
    [queue addOperation:operation];
    
    previousOperation = operation;
    operation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"Starting #2");
        sleep(3);
        NSLog(@"Finishing #2");
    }];
    [operation addDependency:previousOperation];
    [queue addOperation:operation];
    
    previousOperation = operation;
    operation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"Starting #3");
        sleep(3);
        NSLog(@"Finishing #3");
    }];
    [operation addDependency:previousOperation];
    [queue addOperation:operation];
    
  3. 您还可以使用dispatch_queue_create. 除了使用 GCD 而不是NSOperationQueue.

    例如:

    dispatch_queue_t queue = dispatch_queue_create("com.ConnerDouglass.operationtest", 0);
    
    dispatch_async(queue, ^{
        NSLog(@"Starting #1");
        sleep(3);
        NSLog(@"Finishing #1");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"Starting #2");
        sleep(3);
        NSLog(@"Finishing #2");
    });
    
    dispatch_async(queue, ^{
        NSLog(@"Starting #3");
        sleep(3);
        NSLog(@"Finishing #3");
    });
    
于 2013-03-13T22:42:54.710 回答
1

我认为这是一个有趣的解决方案:https ://github.com/berzniz/Sequencer

于 2013-03-13T22:46:10.527 回答
0

像这样的东西怎么样:

-(void)start
{
    // Start the async chain
    [self performSelectorInBackground:@selector(action1) withObject:nil];
}
-(void)notifyDone:(NSNumber *)taskID
{
    NSLog(@"Done with task #%i", taskID.intValue);
}
-(void)action1
{
    // Do some fancy async stuff here
    // Now, we are done. Notify the main thread that task 1 is complete.
    [self performSelectorOnMainThread:@selector(nofityDone:) withObject:[NSNumber numberWithInt:1] waitUntilDone:YES];
    // Move onto the next task once the main thread is done handling the notification
    [self action2];
}
-(void)action2
{
    // Do the same sort of thing as "action1" did, then call he next method
}
于 2013-03-13T22:43:57.613 回答