Я хочу приостановить свое приложение в определенной точке. Другими словами, я хочу, чтобы мое приложение выполняло код, но затем в определенный момент делает паузу в течение 4 секунд, а затем продолжает работу с остальной частью кода. Как я могу это сделать?
Я использую Swift.
Ответы:
Вместо режима сна, который заблокирует вашу программу, если она вызывается из потока пользовательского интерфейса, рассмотрите возможность использования
NSTimer
или таймера отправки.Но, если вам действительно нужна задержка в текущем потоке:
Это использует
sleep
функцию из UNIX.источник
Использование
dispatch_after
блока в большинстве случаев лучше, чем использование,sleep(time)
поскольку поток, в котором выполняется спящий режим, заблокирован от выполнения другой работы. при использованииdispatch_after
потока, над которым работает, не блокируется, поэтому он может выполнять другую работу в то же время.Если вы работаете с основным потоком приложения, его использование
sleep(time)
плохо влияет на работу вашего приложения, поскольку пользовательский интерфейс в это время не отвечает.Отправка после планирования выполнения блока кода вместо замораживания потока:
Swift ≥ 3.0
Swift <3.0
источник
.now() + .seconds(4)
выдает ошибку:expression type is ambiguous without more context
.now() + .seconds(5)
это просто.now() + 5
Сравнение разных подходов в Swift 3.0
1. спать
Этот метод не имеет обратного вызова. Поставьте коды сразу после этой строки, которая будет выполнена через 4 секунды. Это остановит пользователя от перебора элементов пользовательского интерфейса, таких как кнопка тестирования, до тех пор, пока не пройдет время. Несмотря на то, что кнопка начинает зависать при сне, другие элементы, такие как индикатор активности, все еще вращаются без остановки. Вы не можете вызвать это действие снова во время сна.
2. Отправка, выполнение и таймер
Эти три метода работают одинаково, все они работают в фоновом потоке с обратными вызовами, только с разным синтаксисом и немного другими функциями.
Диспетчеризация обычно используется для запуска чего-либо в фоновом потоке. Он имеет обратный вызов как часть вызова функции
Выполнение на самом деле упрощенный таймер. Он устанавливает таймер с задержкой, а затем запускает функцию с помощью селектора.
И, наконец, таймер также предоставляет возможность повторить обратный вызов, что в данном случае бесполезно.
Для всех этих трех методов, когда вы нажимаете на кнопку, чтобы вызвать их, пользовательский интерфейс не останавливается, и вы можете нажать на него снова. Если вы нажмете на кнопку еще раз, будет установлен другой таймер, и обратный вызов будет запущен дважды.
В заключение
Ни один из четырех методов не работает достаточно хорошо сам по себе.
sleep
отключит взаимодействие с пользователем, поэтому экран « зависает » (не на самом деле) и приводит к плохому взаимодействию с пользователем. Три других метода не замораживают экран, но вы можете запускать их несколько раз, и в большинстве случаев вам нужно подождать, пока вы не перезвоните, прежде чем позволить пользователю повторить вызов.Так что лучшим дизайном будет использование одного из трех асинхронных методов с блокировкой экрана. Когда пользователь нажимает кнопку, закройте весь экран каким-нибудь полупрозрачным изображением с вращающимся индикатором активности сверху, сообщая пользователю, что нажатие кнопки обрабатывается. Затем удалите представление и индикатор в функции обратного вызова, сообщая пользователю, что действие выполнено правильно, и т. Д.
источник
@objc
функцию обратного вызова для этойperform(...)
опции. Как и так:@objc func callback() {
Я согласен с Палле, что использование
dispatch_after
здесь - хороший выбор . Но вам, вероятно, не нравятся вызовы GCD, поскольку они довольно раздражают, когда пишут . Вместо этого вы можете добавить этот удобный помощник :Теперь вы просто задерживаете свой код в фоновом потоке, например так:
Задержка кода в главном потоке еще проще:
Если вы предпочитаете Framework, в котором также есть несколько удобных функций, обратитесь к HandySwift . Вы можете добавить его в свой проект через Carthage или Accio, а затем использовать его точно так же, как в примерах выше:
источник
DispatchTime
не было доступно в Swift 2. Это былоlet dispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(seconds * Double(NSEC_PER_SEC)))
раньше.Вы также можете сделать это с помощью Swift 3.
Выполните функцию после задержки следующим образом.
источник
В Swift 4.2 и Xcode 10.1
У вас есть 4 способа отложить. Из этого варианта 1 предпочтительно вызывать или выполнять функцию через некоторое время. Функция sleep () используется меньше всего.
Опция 1.
Вариант 2
Вариант 3
Вариант 4
Если вы хотите вызвать функцию через некоторое время для выполнения чего-либо, не используйте sleep .
источник
NSTimer
Ответ @nneonneo предложил использовать,
NSTimer
но не показал, как это сделать. Это основной синтаксис:Вот очень простой проект, чтобы показать, как его можно использовать. При нажатии кнопки запускается таймер, который вызывает функцию через полсекунды.
Использование
dispatch_time
(как в ответе Палле ) является еще одним допустимым вариантом. Тем не менее, это трудно отменить . С помощьюNSTimer
, чтобы отменить отложенное событие до того, как оно произойдет, все, что вам нужно сделать, это позвонитьИспользование
sleep
не рекомендуется, особенно в основном потоке, так как он останавливает всю работу, выполняемую в потоке.Смотрите здесь для моего более полного ответа.
источник
Попробуйте следующую реализацию в Swift 3.0
использование
источник
Вы можете легко создать расширение для использования функции задержки (Синтаксис: Swift 4.2+)
Как использовать в UIViewController
источник
Если вам нужно установить задержку менее секунды, нет необходимости устанавливать параметр .seconds. Надеюсь это кому-нибудь пригодится.
источник
источник
DispatchQueue.main.asyncAfter(deadline: .now() + 4) {/*Do stuff*/}
, вероятно , более правильно ✌️Если ваш код уже выполняется в фоновом потоке, приостановите поток, используя этот метод в Foundation :
Thread.sleep(forTimeInterval:)
Например:
(Смотрите другие ответы для предложений, когда ваш код работает в главном потоке.)
источник
Чтобы создать простую задержку, вы можете импортировать Darwin, а затем использовать sleep (секунд), чтобы сделать задержку. Однако это занимает всего целые секунды, поэтому для более точных измерений вы можете импортировать Дарвин и использовать usleep (миллионные доли секунды) для очень точных измерений. Чтобы проверить это, я написал:
Который печатает, затем ждет в течение 1 секунды и печатает, затем ждет в течение 0,4 секунды, затем печатает. Все работало как положено.
источник
это самый простой
источник