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.

  • iOS: Создать UIImage из фонового потока?
  • Unity3D WWW вызывает основной поток на iOS
  • основной поток выполняет dispatch_async в параллельной очереди в viewDidLoad или в рамках метода
  • Почему NSOperationQueue быстрее, чем GCD или выполняетSelectorOnMainThread, когда обрабатывает большое количество задач в основном потоке?
  • Убедившись, что я правильно объясняю вложенный GCD
  • Объединение нескольких контекстов дочерних управляемых объектов
  • Core-Data executeFetchRequest задерживает приложение в фоновом потоке
  • Тема убивает ОС
  • Многопоточность iOS - обновления NSURLSession и UI
  • Создавать фоновый прогон в iOS
  • iphone ios работает в отдельной теме
  • Interesting Posts

    Как принять во внимание поворот экрана при проектировании 3D-сцены?

    цель-C как объявить частную собственность для категории?

    Анимация UICollectionView и UICollectionViewCell с использованием фреймворка POP

    NSInvalidArgumentException ', reason:' – : непризнанный селектор, отправленный в экземпляр 0x712e450 '

    Точность определения местоположения CLLocation

    Являются ли viewDidUnload и dealloc всегда вызываемыми при срыве UIViewController?

    Позиционирование UIView после CAKeyframeAnimation приводит к сбою отображения

    openCV 2.4.8 Исходные ошибки компоновщика iOS 7.0

    Симулятор IOS SigKill

    Язык выбора для CoreAudio

    Использование SVG-файлов с помощью монотота

    Ошибка _BSMachError: (os / kern) недопустимая возможность (20) после получения удаленного уведомления при добавлении записи CloudKit

    Недопустимый идентификатор приложения с приложением Facebook iOS

    UILabel UILongPressGestureRecognizer не работает?

    Что может вызвать SIGABRT на dispatch_async в iOS9.1?

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