延迟循环(倒计时功能)
Delaying the loop (countdown func)
我看了很多文章,none 的答案是正确的。我知道这些方法有效,但在 for 循环中它们不起作用。我如何创建一个倒计时功能 - 我可以在其中打印一个数组,中间有一秒的延迟。
let array = [9, 8, 7, 6, 5, 4, 3, 2, 1]
我试过这个:
for n in array {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
print(n)
}
}
并在 1 秒后打印 所有数字。所以我尝试了这个:
override func viewDidLoad() {
super.viewDidLoad()
let timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: (#selector(printer)), userInfo: nil, repeats: true)
}
@objc func printer() {
for n in array {
print(n)
}
}
同样的结果。我想这些都是很好的方法,但有些地方不对。
试试这个代码
let array = [9, 8, 7, 6, 5, 4, 3, 2, 1]
DispatchQueue.global().async {
for n in array {
sleep(1)
print(n)
}
}
当你使用这个DispatchQueue
是不正确的,因为它会被等待然后打印所有
为计时器创建一个计数器变量和另一个变量
var counter = 0
var timer : Timer?
在viewDidLoad
中创建定时器
override func viewDidLoad() {
super.viewDidLoad()
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(printer), userInfo: nil, repeats: true)
}
在操作方法中增加 counter
变量并在达到数组中的项目数时使计时器无效。
@objc func printer() {
print(array[counter])
counter += 1
if counter == array.count {
timer?.invalidate()
timer = nil
}
}
另一种方法是DispatchSourceTimer
,它避免了@objc
运行时
var timer : DispatchSourceTimer?
let interval : DispatchTime = .now() + .seconds(1)
timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
timer!.schedule(deadline:interval, repeating: 1)
var index = 0
timer!.setEventHandler {
// DispatchQueue.main.async {
print(array[index])
}
index += 1
if index == array.count {
timer!.cancel()
timer = nil
}
}
timer!.resume()
For 循环几乎同时运行所有分派,因此所有分派都具有相同的等待时间,您可以像这样依赖它
let array = [9, 8, 7, 6, 5, 4, 3, 2, 1]
for i in 0...array.count-1 {
DispatchQueue.main.asyncAfter(deadline: .now() + Double(i) ) {
print(array[i])
}
}
我是这样倒计时的。不知道这样对不对,但确实有效
var timeRemaining: Int = 60
countdown()
func countdown() {
if self.timeRemaining > 0 {
DispatchQueue.main.asyncAfter(deadline: .now() + 1 ) {
self.timeRemaining -= 1
self.countdown()
}
}
}
我看了很多文章,none 的答案是正确的。我知道这些方法有效,但在 for 循环中它们不起作用。我如何创建一个倒计时功能 - 我可以在其中打印一个数组,中间有一秒的延迟。
let array = [9, 8, 7, 6, 5, 4, 3, 2, 1]
我试过这个:
for n in array {
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
print(n)
}
}
并在 1 秒后打印 所有数字。所以我尝试了这个:
override func viewDidLoad() {
super.viewDidLoad()
let timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: (#selector(printer)), userInfo: nil, repeats: true)
}
@objc func printer() {
for n in array {
print(n)
}
}
同样的结果。我想这些都是很好的方法,但有些地方不对。
试试这个代码
let array = [9, 8, 7, 6, 5, 4, 3, 2, 1]
DispatchQueue.global().async {
for n in array {
sleep(1)
print(n)
}
}
当你使用这个DispatchQueue
是不正确的,因为它会被等待然后打印所有
为计时器创建一个计数器变量和另一个变量
var counter = 0
var timer : Timer?
在viewDidLoad
中创建定时器
override func viewDidLoad() {
super.viewDidLoad()
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(printer), userInfo: nil, repeats: true)
}
在操作方法中增加 counter
变量并在达到数组中的项目数时使计时器无效。
@objc func printer() {
print(array[counter])
counter += 1
if counter == array.count {
timer?.invalidate()
timer = nil
}
}
另一种方法是DispatchSourceTimer
,它避免了@objc
运行时
var timer : DispatchSourceTimer?
let interval : DispatchTime = .now() + .seconds(1)
timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
timer!.schedule(deadline:interval, repeating: 1)
var index = 0
timer!.setEventHandler {
// DispatchQueue.main.async {
print(array[index])
}
index += 1
if index == array.count {
timer!.cancel()
timer = nil
}
}
timer!.resume()
For 循环几乎同时运行所有分派,因此所有分派都具有相同的等待时间,您可以像这样依赖它
let array = [9, 8, 7, 6, 5, 4, 3, 2, 1]
for i in 0...array.count-1 {
DispatchQueue.main.asyncAfter(deadline: .now() + Double(i) ) {
print(array[i])
}
}
我是这样倒计时的。不知道这样对不对,但确实有效
var timeRemaining: Int = 60
countdown()
func countdown() {
if self.timeRemaining > 0 {
DispatchQueue.main.asyncAfter(deadline: .now() + 1 ) {
self.timeRemaining -= 1
self.countdown()
}
}
}