Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/105.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 延迟循环(倒计时功能)_Ios_Swift_For Loop_Delay - Fatal编程技术网

Ios 延迟循环(倒计时功能)

Ios 延迟循环(倒计时功能),ios,swift,for-loop,delay,Ios,Swift,For Loop,Delay,我看过很多文章,没有一篇是正确的。我知道这些方法是有效的,但在for循环中它们并不有效。如何创建一个倒计时函数?在这个函数中,我可以打印一个数组,中间有一秒的延迟 let array = [9, 8, 7, 6, 5, 4, 3, 2, 1] 我试过这个: for n in array { DispatchQueue.main.asyncAfter(deadline: .now() + 1) { print(n)

我看过很多文章,没有一篇是正确的。我知道这些方法是有效的,但在for循环中它们并不有效。如何创建一个倒计时函数?在这个函数中,我可以打印一个数组,中间有一秒的延迟

let array = [9, 8, 7, 6, 5, 4, 3, 2, 1]
我试过这个:

for n in array {
            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                print(n)
            }
        }
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)
        }
    }
它会在1秒后打印所有的数字。所以我试了一下:

for n in array {
            DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                print(n)
            }
        }
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)
        }  
    }
使用此
调度队列时
是不正确的,因为它将被等待保留,然后打印所有

请尝试此代码

let array = [9, 8, 7, 6, 5, 4, 3, 2, 1]

    DispatchQueue.global().async {
        for n in array {
            sleep(1)
            print(n)
        }  
    }

使用此
调度队列时
是不正确的,因为它将通过等待保持,然后全部打印

为计时器创建一个计数器变量和另一个变量

var counter = 0
var timer : Timer?
override func viewDidLoad() {
    super.viewDidLoad()
    timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(printer), userInfo: nil, repeats: true)
}
viewDidLoad
中创建计时器

var counter = 0
var timer : Timer?
override func viewDidLoad() {
    super.viewDidLoad()
    timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(printer), userInfo: nil, repeats: true)
}
在操作方法中,增加
计数器
变量,如果达到数组中的项目数,则使计时器无效

@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()

为计时器创建一个计数器变量和另一个变量

var counter = 0
var timer : Timer?
override func viewDidLoad() {
    super.viewDidLoad()
    timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(printer), userInfo: nil, repeats: true)
}
viewDidLoad
中创建计时器

var counter = 0
var timer : Timer?
override func viewDidLoad() {
    super.viewDidLoad()
    timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(printer), userInfo: nil, repeats: true)
}
在操作方法中,增加
计数器
变量,如果达到数组中的项目数,则使计时器无效

@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])
  }
}

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])
  }
}


如果你想在不同的时间打印数字,那么你应该在
asyncAfter(截止日期:)
中使用不同的偏移量,可能重复:@AhmadF:如果你认为这是一个重复的问题,请关闭该问题。这样,您就不必显式地编写可能的副本。它本身就是一个评论。@Nitish我不打算投票关闭它,因为我不确定OP的确切情况,不过我提到了它,以防它有用。。。谢谢你的留言(顺便说一句:)@AhmadF:我明白了。谢谢!!如果你想在不同的时间打印数字,那么你应该在
asyncAfter(截止日期:)
中使用不同的偏移量,可能重复:@AhmadF:如果你认为这是一个重复的问题,请关闭该问题。这样,您就不必显式地编写可能的副本。它本身就是一个评论。@Nitish我不打算投票关闭它,因为我不确定OP的确切情况,不过我提到了它,以防它有用。。。谢谢你的留言(顺便说一句:)@AhmadF:我明白了。谢谢!!这只是为了澄清-为什么这是一个比@a.masri更好的解决方案?使用
sleep
是一个非常坏的习惯,因为它会阻塞当前线程<代码>计时器是异步工作的。我想这3个答案都是正确的。这一个,即使它包含更多的代码,对我来说是最清晰的-它有计时器,在func之外运行,并停止计时器。但是,它不用于循环。@Kowboj A
for
循环在这种情况下是错误的设计。不完全正确@什乌·汗的解决方案行不通。而且,问题不在于哪个正确,而在于哪个更好。让我们来看看。这只是为了我的澄清-为什么这是一个比@a.masri更好的解决方案?使用
sleep
是一个非常坏的习惯,因为它会阻塞当前线程<代码>计时器是异步工作的。我想这3个答案都是正确的。这一个,即使它包含更多的代码,对我来说是最清晰的-它有计时器,在func之外运行,并停止计时器。但是,它不用于循环。@Kowboj A
for
循环在这种情况下是错误的设计。不完全正确@什乌·汗的解决方案行不通。而且,问题不在于哪个正确,而在于哪个更好。让我们看看。我不是落选的选民,但我可以猜你的答案是落选的,因为它阻止了线索。如果你在主线程上运行它,你的界面将冻结9秒。@JeremyP这一点没有被问题所澄清,基本上你可以在
DispatchQueue.globel中使用for循环,无论你使用哪个线程,你都在使用该线程9秒来做最少的工作,并且
sleep()
只保证线程至少休眠一秒钟,这意味着您的计时会逐渐变得更加扭曲。@vadian的解决方案不会占用线程,并将提供更精确的间隔。@a.masri:它不是在问题中指定的,而是由标记指定的。OP标记了[iOS],没有人想要一个被阻止的应用。@vikingosegundo我已经编辑了答案,但让我们看看他在主线程上做的问题,在标记中他没有提到我不是被否决的投票人,但我可以猜你的答案被否决了,因为它阻止了线程。如果你在主线程上运行它,你的界面将冻结9秒。@JeremyP这一点没有被问题所澄清,基本上你可以在
DispatchQueue.globel中使用for循环,无论你使用哪个线程,你都在使用该线程9秒来做最少的工作,并且
sleep()
只保证线程至少休眠一秒钟,这意味着您的计时会逐渐变得更加扭曲。@vadian的解决方案不会占用线程,并将提供更精确的间隔。@a.masri:它不是在问题中指定的,而是由标记指定的。OP标记了[iOS],没有人想要一个被阻止的应用程序。@vikingosegundo我已经编辑了答案,但让我们看看他在主线程上做的问题,在标记中他没有提到它