Вложенный dispatch_async (dispatch_async внутри другого dispatch_async)

Как правильно вызывать dispatch_async вызовы внутри dispatch_async

dispatch_group_t downloadQueue = dispatch_group_create();
dispatch_group_async(downloadQueue,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {

NSLog(@"Main");
[NSThread sleepForTimeInterval:5.0];
NSLog(@"End");

    [self myMethod];

});
dispatch_group_notify(downloadQueue,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0), ^ {

    NSLog(@"FINAL");

});

и вот мой метод:

-(void)myMethod
{
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
        // block1
        NSLog(@"Block1");
        [NSThread sleepForTimeInterval:5.0];
        NSLog(@"Block1 End");
    });
    dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
        // block2
        NSLog(@"Block2");
        [NSThread sleepForTimeInterval:8.0];
        NSLog(@"Block2 End");
    });

    dispatch_group_notify(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
        // block3
        NSLog(@"Block3");
    });
}

и мой вывод:
Основной
Конец
Блок 1
Блок 2
ФИНАЛЬНЫЙ
Блок 1 Конец
Блок 2 Конец
Блок 3

но мне нужно
Основной
Конец
Блок 1
Блок 2
Блок 1 Конец
Блок 2 Конец
Блок 3
ФИНАЛ


person Deepak Kumar    schedule 10.11.2016    source источник
comment
Ваша проблема в том, что myMethod является асинхронным, поэтому он будет отправлять свои блоки, а затем возвращаться, выходя из внешней группы отправки. Используйте dispatch_group_enter и dispatch_group_leave, а не dispatch_group_async   -  person Paulw11    schedule 10.11.2016


Ответы (2)


Вам просто нужно получить уведомление с вашей группой myMethod. Ваш код будет:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {

    NSLog(@"Main");
    [NSThread sleepForTimeInterval:5.0];
    NSLog(@"End");

    dispatch_group_notify([self myMethod],dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0), ^ {

        NSLog(@"FINAL");

    });
});

-(dispatch_group_t)myMethod{

    dispatch_group_t group = dispatch_group_create();

    dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
        // block1
        NSLog(@"Block1");
        [NSThread sleepForTimeInterval:5.0];
        NSLog(@"Block1 End");
    });


    dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
        // block2
        NSLog(@"Block2");
        [NSThread sleepForTimeInterval:8.0];
        NSLog(@"Block2 End");
    });

    dispatch_group_notify(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^ {
        // block3
        NSLog(@"Block3");
    });
    return group;
}
person Cy-4AH    schedule 10.11.2016

Вы можете использовать dispatch_group_wait в myMethod вместо dispatch_group_notify. Таким образом, ваш метод вернется только после завершения выполнения обоих dispatch_group_async.

person stefos    schedule 10.11.2016