2014-05-17 3 views
0

У меня это ниже в приложении iOS. Я учу GCD. поэтому, пробуя простые вещи.Поведение метода async GCD непонятно

Здесь вывод этого меня сбивает с толку. Почему всегда начинается 2. набор утверждений, а затем 1.? Несмотря на то, что я отправляю две задачи в GCD, сначала отправлю 1. сначала поставлю. Это не очень большая задача, так что 1. set и 2.set будут перекрываться во времени. Его простая задача - напечатать потоки, на которых он работает.

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

Опишите.

2. Crnt Thread = <NSThread: 0x10920fee0>{name = (null), num = 1} 
2. Main thread = <NSThread: 0x10920fee0>{name = (null), num = 1} 
1. Crnt Thread = <NSThread: 0x10920fee0>{name = (null), num = 1} 
1. Main thread = <NSThread: 0x10920fee0>{name = (null), num = 1} 
3. Crnt Thread = <NSThread: 0x10920fee0>{name = (null), num = 1} 
3. Main thread = <NSThread: 0x10920fee0>{name = (null), num = 1} 

Код здесь:

void displayAlertView(void *paramContext) 
{ 

    NSLog(@"3. Crnt Thread = %@",[NSThread currentThread]); 
    NSLog(@"3. Main thread = %@", [NSThread mainThread]); 
} 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    // Override point for customization after application launch. 
    dispatch_queue_t myQueue = dispatch_get_main_queue(); 
    AlertViewData *contextData = (AlertViewData *)malloc(sizeof(AlertViewData)); 
    dispatch_async(myQueue,^(void){ 
     NSLog(@"1. Crnt Thread = %@",[NSThread currentThread]); 
     NSLog(@"1. Main thread = %@", [NSThread mainThread]); 
    }); 
    if(contextData != NULL) 
    { 
     NSLog(@"2. Crnt Thread = %@",[NSThread currentThread]); 
     NSLog(@"2. Main thread = %@", [NSThread mainThread]); 

     dispatch_async_f(myQueue, contextData, displayAlertView); 
    } 

    return YES; 
} 

ответ

0

«2» заявления приходят первых, потому, что код становится выполняться до того, как асинхронный блок имел шанс быть установки и запуска. В этом весь смысл dispatch_async. Такой код запускается в другом потоке, в то время как текущий поток продолжает свой веселый путь.

Если вы обновили оба блока кода, чтобы использовать цикл, который регистрирует 100 операторов журналов, вы, вероятно, увидите некоторое смешение операторов «1» и «2».

Но с двумя журналами они бывают настолько быстрыми, что журналы «2» заполняются до того, как блок с «1» журналами имел шанс зайти. Посмотрите на отметки времени в журнале, чтобы увидеть.

ОБНОВЛЕНИЕ

Выше было написано в предположении, что myQueue был фон очереди. Как отметил Мартин, это главная очередь. Так как это главная очередь, ответ немного отличается.

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

Текущий код находится в начале строки. Когда вы вызываете dispatch_async для блока с журналами «1», этот блок добавляется в конец строки и будет запускаться при выполнении текущего кода. Затем вы вызываете dispatch_async_f для журналов «3». Они добавляются в конец строки (после «1» журналов).

Итак, как только текущая runloop завершается (и возвращается метод didFinishLaunchingWithOptions`), выполняется следующий бит в строке. Это ваши журналы «1». Когда это будет сделано, будет запущен следующий блок в очереди (ваши «3» журналы).

+1

Не совсем правильно, я думаю. Блок отправляется в очередь * main *, которая выполняется только в основном потоке. Он выполняется, когда didFinishLaunchingWithOptions возвращается, потому что это очередная очередь. –

+0

@rmaddy: Не могли бы вы объяснить подробно? Блоки GCD дают больше накладных расходов на ядро ​​процессора, чем вызов нормальной функции? Вот почему сначала запускается 2 набора инструкций? – Chandu

+0

@MartinR К сожалению, я забыл, что 'myQueue' - главная очередь. Я соответствующим образом обновлю ответ. – rmaddy

Смежные вопросы