GCD — как ждать в основном потоке асинхронного обратного вызова, который выполняется в основной очереди

Я хочу выполнить 2 блока один за другим, где каждый из них выполняется асинхронно.

Например

[someMethodWithCompletionHandler:^() {
  // do something in the completion handler
}];

[anotherMethodWithCompletionHandler:^ {
  // do something else in the completion handler after the first method completes
}];

Теперь мне нужно, чтобы 'anotherMethodWithCompletionHandler' произошло после завершения 'someMethodWithCompletionHandler' (включая его обработчик завершения)

регулярно я бы создал dispatch_group и ждал между двумя методами (я не могу вложить 2 метода в другой обработчик завершения, потому что для этого потребуется много кода для перемещения)

Но проблема в том, что первый блок обработчика завершения вызывается в основном потоке (сам метод вызывает блок в основном потоке), поэтому я не могу эффективно создать dispatch_group, блокирующий основной поток.

Итак, состояние потока выглядит примерно так

// main thread here

[self doFirstPortionOfWork];

// main thread here
[self doSecondPortionOfWork];


-(void)doFirstPortionOfWork
{
.. a lot of stuff happening
  [someMethodWithCompletionHandler:^{
  // this is the main thread
  }];
// would like to block the return here until the completion handler finishes
}

-(void)doSecondPortionOfWork
{
... a lot of work here
  [anotherMethodWithCompletionHandler^{
  // this is also called into the main thread
  }];
// would like to block the return here until the completion handler finishes
}

Итак, как я могу сделать это, не прибегая к множеству вложенных методов, и иметь возможность блокировать основной поток до тех пор, пока все не будет завершено?


person Avner Barr    schedule 27.06.2014    source источник


Ответы (1)


Основной поток аналогичен основной очереди

Невозможно ждать в основном потоке будущей работы в основном потоке. Вы блокируете будущую работу.

Вы можете сделать это следующим образом:

[someMethodWithCompletionHandler:^() {
    // do something in the completion handler
    [anotherMethodWithCompletionHandler:^ {
       // do something else in the completion handler after the first method completes
    }];
}];
person Tricertops    schedule 27.06.2014
comment
Я не могу этого сделать, потому что у меня нет вложенности - person Avner Barr; 28.06.2014
comment
Я не понимаю, что вы подразумеваете под «у меня нет вложенности». - person Tricertops; 28.06.2014