2017-02-22 26 views
0

У меня есть два API вызовов следующим образом:dispatch_async понимания порядка выполнение

-(void) doTask1{ 

    dispatch_async(queueSerial, ^{ //B1 

    [fileObj setFileInfo:file]; 

    }); 
} 

-(void) doTask2{ 

    dispatch_async(queueSerial, ^{ //B2 

     [fileObj getFileInfo:fileName completion:^(NSError *error) { 
      dispatch_async(queueSerial2, ^{ 
       //completion work C1 
      }); 
     }] 

    }); 
} 

Теперь мой вопрос, от того, что я уже понимаю, читая о НОДЕ, если процесс вызывает doTask1 и сразу после звонков doTask2, это приведет к тому, что обе они будут поставлены в очередь и B1 впереди B2.

Однако, действительно ли это, что B1 полностью выполнен до того, как B2 начинает выполнение? Поскольку файл, обновленный на B1, используется B2.

Если B2 начинает выполнять до того, как B1 полностью завершен, это может привести к некоторым проблемам.

Или лучше сделать

-(void) doTask1{ 
    dispatch_sync(queueSerial, ^{B1}); 
} 

-(void) doTask2{ 
    dispatch_sync(queueSerial, ^{B2}); 
} 

ответ

1

Если queueSerial действительно является последовательной очереди, то B1 будет завершена до начала B2. Нет никаких гарантий относительно взаимосвязи между теми, которые называются методами doTaskN ..., на которые повлияет модификация _sync.

Если B1 или B2 отправляют сами, это также не контролируется сериализацией.

+0

Спасибо за ваш комментарий. Я изменил свой вопрос, чтобы добавить более подробную информацию о коде. То, что я не понимаю, это ваш комментарий о том, что «нет никаких гарантий относительно отношений между ними» Что это значит? – ExceptionHandler

+0

Я имею в виду, что в асинхронном случае любые вызовы кода doTask1(), doTask2(), возможно, продолжали выполнять различные другие операции до завершения отправляемой работы. В случае синхронизации вызывающий абонент также останавливается, пока не завершится операция последовательной очереди. –

+0

Я вижу. Я понимаю эту часть. Если B2 отправляет обработчик завершения в другую очередь, возможно ли, чтобы этот блок завершения был выполнен до завершения B1? Есть ли способ убедиться, что этого не произойдет и что блок завершения в B2 ждет завершения B1? – ExceptionHandler

0

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

-(void) doTask1{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
    //your code 
    }); 
} 

-(void) doTask2{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
    //your code 
    }); 
} 

Вот великое объяснение НОД и NSOperation для параллелизм: https://www.appcoda.com/ios-concurrency/

Вы должны быть уверены, что обе задачи отправляются в ту же очередь.

Обновление: Другим подходом является использование NSOperation, потому что вы можете установить зависимость между заданием, чтобы убедиться, что она завершена, прежде чем запускать другую.

0

Если задача B1, отправленная в последовательную очередь, не инициирует ничего асинхронного, то вы уверены, что B1 завершит работу до начала B2. Но если B1 делает что-то асинхронное (например, сетевой запрос и т. Д.), Тогда вам нужны другие шаблоны, чтобы убедиться, что B2 не запускается до завершения асинхронной задачи B1 (например, реализовать собственные обработчики завершения, использовать dispatch_group_notify, обернуть задачи в асинхронном пользовательском NSOperation подклассах и т. д.).

+0

Я немного изменил вопрос и создал новый вопрос [здесь] (http://stackoverflow.com/questions/42403595/forcing-the-order-of-execution-using-dispatch-sync). Сможете ли вы помочь мне разобраться в этом? Я не уверен, как я должен использовать вызов 'dispatch_group_notify' здесь, поскольку они представляют собой два разных метода – ExceptionHandler