Sch*_*999 230 xcode delay swift
我想暂时停止我的应用程序.换句话说,我希望我的应用程序执行代码,但在某个时刻,暂停4秒,然后继续执行其余代码.我怎样才能做到这一点?
我正在使用Swift.
Pal*_*lle 313
dispatch_after在大多数情况下,使用块比使用sleep(time)阻止执行其他工作的线程更好.当使用工作dispatch_after的线程没有被阻止时,它可以在此期间做其他工作.
如果您正在处理应用程序的主线程,则使用对应用程序sleep(time)的用户体验不利,因为UI在此期间没有响应.
在调度执行代码块而不是冻结线程之后调度:
let seconds = 4.0
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
// Put your code which should be executed with a delay here
}
Run Code Online (Sandbox Code Playgroud)
let time = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 4 * Int64(NSEC_PER_SEC))
dispatch_after(time, dispatch_get_main_queue()) {
// Put your code which should be executed with a delay here
}
Run Code Online (Sandbox Code Playgroud)
nne*_*neo 240
如果从UI线程调用将锁定程序,而不是睡眠,请考虑使用NSTimer或调度计时器.
但是,如果你真的需要在当前线程中延迟:
do {
sleep(4)
}
Run Code Online (Sandbox Code Playgroud)
这使用了sleepUNIX中的函数.
Fan*_*ing 40
swift 3.0中不同方法的比较
1.睡觉
此方法没有回调.在此行之后直接放置代码将在4秒内执行.它将阻止用户使用测试按钮之类的UI元素进行迭代,直到时间消失.虽然按钮在睡眠开始时有点冻结,但活动指示器等其他元素仍在旋转而不会冻结.在睡眠期间,您无法再次触发此操作.
sleep(4)
print("done")//Do stuff here
Run Code Online (Sandbox Code Playgroud)
2.派遣,执行和计时器
这三种方法的工作方式类似,它们都在带有回调的后台线程上运行,只是语法不同,功能略有不同.
Dispatch通常用于在后台线程上运行某些东西.它将回调作为函数调用的一部分
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(4), execute: {
print("done")
})
Run Code Online (Sandbox Code Playgroud)
Perform实际上是一个简化的计时器.它设置一个带延迟的定时器,然后通过选择器触发功能.
perform(#selector(callback), with: nil, afterDelay: 4.0)
func callback() {
print("done")
}}
Run Code Online (Sandbox Code Playgroud)
最后,计时器还提供了重复回调的功能,这在这种情况下无用
Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(callback), userInfo: nil, repeats: false)
func callback() {
print("done")
}}
Run Code Online (Sandbox Code Playgroud)
对于所有这三种方法,当您单击按钮触发它们时,UI不会冻结,您可以再次单击它.如果再次单击该按钮,则会设置另一个计时器,并且将触发两次回调.
结论
这四种方法中没有一种能够单独运行.sleep将禁用用户交互,因此屏幕" 冻结 "(实际上并不是)并导致糟糕的用户体验.其他三种方法不会冻结屏幕,但您可以多次触发它们,而且大多数情况下,您希望等到收到回叫之后才允许用户再次拨打电话.
因此,更好的设计将使用屏幕阻止的三种异步方法之一.当用户点击按钮时,在整个屏幕上覆盖一些半透明视图,顶部有旋转活动指示器,告诉用户正在处理按钮点击.然后删除回调函数中的视图和指示器,告诉用户操作已正确处理等.
Jee*_*hut 30
我同意Palle的说法,在这里使用dispatch_after是个不错的选择.但是你可能不喜欢GCD调用,因为它们写起来很烦人.相反,你可以添加这个方便的助手:
public func delay(bySeconds seconds: Double, dispatchLevel: DispatchLevel = .main, closure: @escaping () -> Void) {
let dispatchTime = DispatchTime.now() + seconds
dispatchLevel.dispatchQueue.asyncAfter(deadline: dispatchTime, execute: closure)
}
public enum DispatchLevel {
case main, userInteractive, userInitiated, utility, background
var dispatchQueue: DispatchQueue {
switch self {
case .main: return DispatchQueue.main
case .userInteractive: return DispatchQueue.global(qos: .userInteractive)
case .userInitiated: return DispatchQueue.global(qos: .userInitiated)
case .utility: return DispatchQueue.global(qos: .utility)
case .background: return DispatchQueue.global(qos: .background)
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您只需将代码延迟到这样的后台线程:
delay(bySeconds: 1.5, dispatchLevel: .background) {
// delayed code that will run on background thread
}
Run Code Online (Sandbox Code Playgroud)
延迟主线程上的代码甚至更简单:
delay(bySeconds: 1.5) {
// delayed code, by default run in main thread
}
Run Code Online (Sandbox Code Playgroud)
如果你更喜欢一个也有一些更方便功能的框架,那么请查看HandySwift.您可以通过Carthage将其添加到项目中,然后使用它与上面的示例完全相同:
import HandySwift
delay(by: .seconds(1.5)) {
// delayed code
}
Run Code Online (Sandbox Code Playgroud)
Cyr*_*cia 24
您也可以使用Swift 3执行此操作.
延迟后执行此功能.
override func viewDidLoad() {
super.viewDidLoad()
self.perform(#selector(ClassName.performAction), with: nil, afterDelay: 2.0)
}
@objc func performAction() {
//This function will perform after 2 seconds
print("Delayed")
}
Run Code Online (Sandbox Code Playgroud)
Sur*_*gch 19
@nneonneo的回答建议使用,NSTimer但没有说明如何做到这一点.这是基本语法:
let delay = 0.5 // time in seconds
NSTimer.scheduledTimerWithTimeInterval(delay, target: self, selector: #selector(myFunctionName), userInfo: nil, repeats: false)
Run Code Online (Sandbox Code Playgroud)
这是一个非常简单的项目,展示如何使用它.当按下一个按钮时,它会启动一个定时器,在延迟半秒后调用一个功能.
import UIKit
class ViewController: UIViewController {
var timer = NSTimer()
let delay = 0.5
// start timer when button is tapped
@IBAction func startTimerButtonTapped(sender: UIButton) {
// cancel the timer in case the button is tapped multiple times
timer.invalidate()
// start the timer
timer = NSTimer.scheduledTimerWithTimeInterval(delay, target: self, selector: #selector(delayedAction), userInfo: nil, repeats: false)
}
// function to be called after the delay
func delayedAction() {
print("action has started")
}
}
Run Code Online (Sandbox Code Playgroud)
使用dispatch_time(如Palle的答案)是另一个有效选项.但是,很难取消.有了NSTimer,要在事件发生之前取消延迟事件,您需要做的就是打电话
timer.invalidate()
Run Code Online (Sandbox Code Playgroud)
使用sleep不推荐,尤其是在主线程,因为它停止的线程上正在做的所有工作.
请看这里我更全面的答案.
Leg*_*ang 16
我相信做 4 秒计时器的最简单和最新的方法是:
Task {
// Do something
// Wait for 4 seconds
try await Task.sleep(nanoseconds: 4_000_000_000)
}
Run Code Online (Sandbox Code Playgroud)
它使用Swift 5.5 的新并发性。
iOS*_*iOS 12
在Swift 4.2和Xcode 10.1中
您总共有4种方法可以延迟。在这些选项1中,最好在一段时间后调用或执行一个函数。的睡眠()是在使用至少情况。
选项1。
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
self.yourFuncHere()
}
//Your function here
func yourFuncHere() {
}
Run Code Online (Sandbox Code Playgroud)
选项2。
perform(#selector(yourFuncHere2), with: nil, afterDelay: 5.0)
//Your function here
@objc func yourFuncHere2() {
print("this is...")
}
Run Code Online (Sandbox Code Playgroud)
选项3。
Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(yourFuncHere3), userInfo: nil, repeats: false)
//Your function here
@objc func yourFuncHere3() {
}
Run Code Online (Sandbox Code Playgroud)
选项4。
sleep(5)
Run Code Online (Sandbox Code Playgroud)
如果您想在一段时间后调用某个函数来执行某些操作,请不要使用sleep。
编辑:
我强烈建议开始使用Swift Concurrency。借助 Swift Concurrency,您可以使用 轻松暂停当前任务Task.sleep。
使用DispatchQueue的.asyncAfter方法,您可以在给定时间后执行代码。因此,例如...1 秒后在主线程上执行如下所示:
DispatchQueue.main.asyncAfter(deadline: .now() + 1) { ... }
Run Code Online (Sandbox Code Playgroud)
使用我方便的Delay包装结构,您可以以更奇特的方式执行它:
struct Delay {
@discardableResult
init(_ timeInterval: TimeInterval, queue: DispatchQueue = .main, executingBlock: @escaping () -> Void) {
queue.asyncAfter(deadline: .now() + timeInterval, execute: executingBlock)
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
Delay(0.4) { ... }
Run Code Online (Sandbox Code Playgroud)
在Swift 3.0中尝试以下实现
func delayWithSeconds(_ seconds: Double, completion: @escaping () -> ()) {
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
completion()
}
}
Run Code Online (Sandbox Code Playgroud)
用法
delayWithSeconds(1) {
//Do something
}
Run Code Online (Sandbox Code Playgroud)
要创建一个简单的时间延迟,您可以导入 Darwin,然后使用 sleep(seconds) 来进行延迟。不过,这只需要整秒,因此为了获得更精确的测量,您可以导入 Darwin 并使用 usleep(百万分之一秒)进行非常精确的测量。为了测试这一点,我写道:
import Darwin
print("This is one.")
sleep(1)
print("This is two.")
usleep(400000)
print("This is three.")
Run Code Online (Sandbox Code Playgroud)
打印,然后等待 1 秒并打印,然后等待 0.4 秒然后打印。一切都按预期进行。
如果需要将延迟设置为小于一秒,则无需设置.seconds参数。我希望这对某人有用。
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
// your code hear
})
Run Code Online (Sandbox Code Playgroud)
DispatchQueue.global(qos: .background).async {
sleep(4)
print("Active after 4 sec, and doesn't block main")
DispatchQueue.main.async{
//do stuff in the main thread here
}
}
Run Code Online (Sandbox Code Playgroud)
如果您的代码已经在后台线程中运行,请在 Foundation 中使用此方法暂停线程:Thread.sleep(forTimeInterval:)
例如:
DispatchQueue.global(qos: .userInitiated).async {
// Code is running in a background thread already so it is safe to sleep
Thread.sleep(forTimeInterval: 4.0)
}
Run Code Online (Sandbox Code Playgroud)
(当您的代码在主线程上运行时,请参阅其他答案以获取建议。)
您可以创建扩展以轻松使用延迟功能(语法:Swift 4.2+)
extension UIViewController {
func delay(_ delay:Double, closure:@escaping ()->()) {
DispatchQueue.main.asyncAfter(
deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure)
}
}
Run Code Online (Sandbox Code Playgroud)
如何在UIViewController中使用
self.delay(0.1, closure: {
//execute code
})
Run Code Online (Sandbox Code Playgroud)
小智 5
使用Task.sleep不会阻止除手头任务之外的任何代码,而且非常简单。
//Delay task by 4 seconds:
Task {
try await Task.sleep(nanoseconds: 4000000000)
//Execute your code here
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
264529 次 |
| 最近记录: |