Задача -c: нужно пояснить следующий код, относящийся к dispatch_async (GCD)

В основном приведенный ниже код работает следующим образом: когда я нажимаю кнопку, обе метки обновляются через 4 секунды с соответствующим текстом одновременно. Однако, если я закомментирую dispatch_async(dispatch_get_main_queue(), ^(void){, мои метки все еще обновляются, но первая метка займет 4 секунды, а вторая метка обновится через 4 секунды после первой метки. Мне интересно, может ли кто-нибудь объяснить, почему обе метки обновляются за 4 секунды с кодом отправки, так сказать, в тупом вопросе Я пытаюсь слушать объяснение учебника, но это только еще больше сбивает меня с толку.

void (^tFunct1)(UILabel *,NSString*) = ^(UILabel *lbl, NSString *src){
 NSLog(@"GO TO SLEEP...");
 sleep(4);
 NSLog(@"WAKING UP...");
dispatch_async(dispatch_get_main_queue(), ^(void){
[lbl setText:src];
NSLog(@"Label Done!");
});

};
 -(IBAction)buttonPressed:(id)sender{
aConCurrentQue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_async(aConCurrentQue ,^{ tFunct1(self ->lblOne, @"1 GO!" ); } );
dispatch_async(aConCurrentQue ,^{ tFunct1(self ->lblTwo, @"2 GO!" ); } );
 }

person Squidward Tennisballs    schedule 22.09.2013    source источник
comment
Кажется странным использовать блок для вызова блока из блока. Просто используйте метод вместо этого. Кроме того, использование -> для доступа к ivars работает, но не является стандартным соглашением. Просто используйте их напрямую.   -  person bbum    schedule 22.09.2013


Ответы (1)


Вы всегда должны выполнять обновления пользовательского интерфейса в основной очереди. Комментируя отправку в основную очередь, вы пытаетесь выполнить обновления пользовательского интерфейса в фоновой глобальной очереди, что объясняет неправильное поведение.

UIKit не предназначен (за некоторыми очень специфическими исключениями) для работы в фоновой очереди, и вам просто не следует обновлять пользовательский интерфейс в фоновой очереди.

person Rob    schedule 22.09.2013
comment
Круто, также просто для ясности, диспетчеризация main Que в основном обрабатывается процессорами, что-то вроде многопоточности, верно? Извините, если я кажусь невежественным в любом случае. Давно пытался разобраться в этой теме. - person Squidward Tennisballs; 22.09.2013
comment
@SquidwardTennisballs Основная очередь — это специальная последовательная очередь, которая выполняет задачи в основном потоке вашего приложения. См. Об очередях отправки в Руководстве по параллельному программированию. Поскольку основная очередь очень важна для своевременных обновлений пользовательского интерфейса, именно поэтому мы отправляем все медленное в фоновую очередь, чтобы не блокировать эту основную очередь. Но, как мы сказали выше, обновления пользовательского интерфейса должны происходить в этой основной очереди. - person Rob; 22.09.2013
comment
Круто, так что используйте фоновую очередь для чего-то вроде загрузки или анализа изображений, что обычно занимает целую вечность. - person Squidward Tennisballs; 22.09.2013
comment
@SquidwardTennisballs Верно. - person Rob; 22.09.2013