CFRunLoopPerformBlock vs dispatch_async

У меня есть некоторые работы по вычислению в фоновом потоке, после чего мне нужно обновить преобразование некоторого числа, я пытаюсь использовать

dispatch_async(dispatch_get_main_queue(), ^{calayer.transform = newTransform}); 

а также

 CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopCommonModes, ^(void) {calayer.transform = newTransform}); 

Я просто думал, что они такие же, но я обнаружил, что калейер работал много плавным (может быть?) При использовании dispatch_async. какова разница между этими двумя функциями?

3 Solutions collect form web for “CFRunLoopPerformBlock vs dispatch_async”

Основное различие здесь заключается в том, что CFRunLoopPerformBlock позволяет указать конкретные режимы цикла выполнения, в которых нужно выполнить блок, тогда как dispatch_async(dispatch_get_main_queue(),...) будет выполняться только в общих режимах. Возможно, больше по поводу проблемы с производительностью, которую вы видите, CFRunLoopPerformBlock не пробуждает основной поток. Из документации для CFRunLoopPerformBlock :

Этот метод блокирует только блок и автоматически не запускает указанный цикл выполнения. Поэтому выполнение блока происходит в следующий раз, когда цикл запуска просыпается, чтобы обрабатывать другой источник ввода. Если вы хотите, чтобы работа была выполнена сразу, вы должны явно разбудить этот поток, используя функцию CFRunLoopWakeUp.

На практике это обычно означает, что ваш блок не будет выполняться до тех пор, пока не будет просыпаться цикл выполнения (т. Е. Происходит пользовательское событие, срабатывает таймер, запускается поток источников запуска, сообщение маха и т. Д.). GCD не является, по своему усмотрению, API, основанный на запуске; взаимосвязь между основной очередью и циклом запуска основного потока является, фактически, деталью реализации. Я ожидал бы, что эта реализация спровоцирует сам цикл выполнения, если это необходимо для обслуживания основной очереди.

Отсутствие информации об обратном, я сильно подозреваю, что это источник разницы в производительности. Я ожидаю, что производительность будет одинаковой, если вы добавили вызов CFRunLoopWakeUp сразу после вашего вызова в CFRunLoopPerformBlock .

Основная очередь GCD – это очередная очередь. Таким образом, он может запускать только одну задачу за раз. Даже если эта задача запускает внутренний цикл цикла – например, запускает модальный диалог, тогда другие задачи, отправленные в основную очередь, не могут выполняться до тех пор, пока это не завершится.

Задачи, представленные с использованием CFRunLoopPerformBlock() могут выполняться всякий раз, когда цикл запуска выполняется в одном из целевых режимов. Это включает в себя выполнение цикла выполнения из задачи, которая была отправлена ​​с использованием CFRunLoopPerformBlock() .

Рассмотрим следующие примеры:

 CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopCommonModes, ^{ printf("outer task milestone 1\n"); CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopCommonModes, ^{ printf("inner task\n"); }); [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; printf("outer task milestone 2\n"); }); 

производит выход как:

 outer task milestone 1 inner task outer task milestone 2 

Хотя это:

 dispatch_async(dispatch_get_main_queue(), ^{ printf("outer task milestone 1\n"); dispatch_async(dispatch_get_main_queue(), ^{ printf("inner task\n"); }); [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; printf("outer task milestone 2\n"); }); 

производит:

 outer task milestone 1 outer task milestone 2 inner task 

Я иногда использую их вместе:

 dispatch_async(dispatch_get_main_queue(), ^(void) { CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopDefaultMode, ^{ // stuff }); }); 

Я использую это для отправки блока в основной поток, который будет выполняться без возникновения «сбоев» при прокрутке UIScrollview.

Я также недавно использовал:

 CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopDefaultMode, ^{ // stuff }); 

вместо:

 [self performSelector:@selector(myMethod:) withObject:myObject afterDelay:0] 

чтобы отложить выполнение кода до следующего прохода через runloop. Таким образом, мне не нужно создавать специальный метод для содержания кода, который я хочу выполнить, и не нужно включать все параметры для выполнения в один (id) myObject.

  • Как избавиться от запаздывания при работе с несколькими потоками
  • Разница между dispatch_async и dispatch_sync в последовательной очереди?
  • Мое приложение iOS зависает, но ошибки не появляется
  • Как отправлять блоки с множеством аргументов на другой поток синхронно?
  • Как обновить пользовательский интерфейс в фоновом потоке в Swift?
  • Как отменить один из многих потоков в быстром
  • Многократная загрузка файлов с блокировкой пользовательского интерфейса в ios
  • Как выполнять два обновления пользовательского интерфейса одновременно?
  • Как создать несколько объектов в фоновом режиме?
  • Рисование в фоновом потоке на iOS
  • Как создать пул автозапуска при использовании
  • Interesting Posts

    xcodebuild: error: Рабочая область с именем «myWorkspace» не содержит схемы с именем

    Размещение UIView для покрытия TabBar & NavBar

    Нечетное поведение UIDatePicker при установке минутыInterval

    Как отправить данные формы в почтовый запрос в iOS?

    Ошибка основной раскадровки в xcode 8 beta

    iOS SDK: воспроизведение музыки на заднем плане и переключение просмотров

    iPad-клавиатура не будет отменена, если модальный стиль представления ViewController – UIModalPresentationFormSheet

    Загрузите сенсорную динамическую 3D-модель

    Как проверить, может ли контроллер просмотра выполнить сеанс

    Передача аргументов в селектор в Swift3

    iOS 8/7 UIWindow с проблемой вращения UIWindowLevelStatusBar

    Разрешить имя NetBIOS на iOS

    iOS: увеличение и уменьшение эффекта на карте

    Приложение содержит или наследует от непубличных классов в полезной нагрузке / XXX.APP / XXX: UIKeyboard

    tableview не работает – : непризнанный селектор, отправленный в экземпляр

    PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.