Подтвердить что ты не робот

Каковы компромиссы между performSelector: withObject: afterDelay: и dispatch_after

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

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

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

Ответ 1

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

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

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

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

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

EDIT: о незапланировании блока, я никогда не пытался отделить блок от очереди, но есть вероятность, что dispatch_release также позволяет вам управлять этим. Если это не так, вы можете определить свою пользовательскую очередь для блока, который вы хотите отменить, и отпустить всю очередь (до того, как блок начнет выполняться), если это когда-либо имеет смысл для вас.

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

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

Ответ 2

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