Каковы компромиссы между executeSelector: withObject: afterDelay: и dispatch_after - PullRequest
21 голосов
/ 01 июня 2011

Единственное функциональное отличие, с которым я столкнулся, заключается в том, что я могу отменить сообщение, назначенное с performSelector:withObject:afterDelay:.Я не знаю, как отменить блок, отправленный на dispatch_after.(Пожалуйста, дайте мне знать, если есть способ сделать это, о котором я не знаю).

Я хотел бы узнать больше о:

  • функциональных компромиссах (Что ещеможет быть достигнуто с одним интерфейсом, но не с другим?)
  • компромиссы производительности (является ли одна реализация более эффективной? В каких случаях?)
  • стилистические компромиссы (Стоит ли отдавать предпочтение одному интерфейсу для определенных задач?лучше следовать общим стилям или соглашениям?)

Ответы [ 2 ]

19 голосов
/ 01 июня 2011

dispatch_after является частью новой Grand Central Dispatch , которая является расширением для iOS и направлена ​​на улучшение одновременного выполнения кода на многоядерном оборудовании.

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

Что касается сравнения с performSelector, я думаю, что одно преимущество dispatch_after справедливо имеет возможность планировать блок без необходимости выбора селектора. См. это обсуждение .

В целом, у меня нет особого опыта работы с GCD, но я бы сказал, что помимо функции блочного планирования, когда вам просто нужно отложить выполнение некоторых селекторов в вашем пользовательском интерфейсе без особой потребности в параллелизме в целом Я бы использовал performSelector.

Если вы подумаете об этом, performSelector дает вам очень плохой параллелизм, поскольку он просто планирует ваш селектор для выполнения в цикле выполнения через минимальное количество времени. С другой стороны, dispatch_after дает вам элемент управления, который в принципе выглядит на уровне наносекунд (!! это то, что я получаю из документов Apple, но я никогда не использовал его, и я не думаю, что на iPhone вы получит это, возможно, на MacOS).

РЕДАКТИРОВАТЬ: о не планировании блока, я никогда не пытался отменить планирование блока из очереди, но есть вероятность, что dispatch_release также позволяет вам контролировать это. Если этого не произойдет, вы можете определить свою пользовательскую очередь для блока, который хотите отменить, и освободить всю очередь (до начала выполнения блока), если это когда-либо имеет для вас смысл.

Что касается производительности, я действительно не знаю, что performSelector делает внутри, но если он планирует поток, то Apple заявляет , что планирование блока с помощью GCD стоит всего 15 инструкций при создании их нить стоит несколько сотен.

Помимо performSelector, не забывайте, что у вас есть возможность использовать NSOperationQueue, который основан на GCD и имеет некоторые накладные расходы, но, по их словам, не такие большие. NSOperationQueue безусловно предлагает возможность отмены.

4 голосов
/ 25 октября 2011

Другим большим преимуществом использования GCD вместо performSelector является возможность очень просто использовать несколько локальных переменных как часть операции блока.Если вы хотите отложить выполнение метода, который принимает более одного аргумента, до более позднего времени, используя performSelector, вам нужно заключить аргументы, которые вы хотите использовать, в другой объект, например, в массив.С dispatch_after вы можете очень просто передать любое количество локальных переменных в блок.Это также относится к необъектам, которые нельзя передать вызову performSelector без предварительного переноса в объект, например NSValue для передачи CGRect.GCD позволяет передавать примитивы, структуры и объекты в операцию, которую вы хотите отложить.

...