ฉันจะเรียกใช้ฟังก์ชันทุกนาทีได้อย่างไร? ใน JavaScript ฉันสามารถทำสิ่งต่างๆเช่นsetIntervalมีสิ่งที่คล้ายกันใน Swift หรือไม่
ผลลัพธ์ที่ต้องการ:
Hello World นาทีละครั้ง ...
ฉันจะเรียกใช้ฟังก์ชันทุกนาทีได้อย่างไร? ใน JavaScript ฉันสามารถทำสิ่งต่างๆเช่นsetIntervalมีสิ่งที่คล้ายกันใน Swift หรือไม่
ผลลัพธ์ที่ต้องการ:
Hello World นาทีละครั้ง ...
คำตอบ:
var helloWorldTimer = NSTimer.scheduledTimerWithTimeInterval(60.0, target: self, selector: Selector("sayHello"), userInfo: nil, repeats: true)
func sayHello() 
{
    NSLog("hello World")
}อย่าลืมนำเข้า Foundation
Swift 4:
 var helloWorldTimer = Timer.scheduledTimer(timeInterval: 60.0, target: self, selector: #selector(ViewController.sayHello), userInfo: nil, repeats: true)
 @objc func sayHello() 
 {
     NSLog("hello World")
 }NSTimerยังคงมีเป้าหมายของมันดังนั้นกับการตั้งค่านี้ถ้าhelloWorldTimerเป็นทรัพย์สินบนselfคุณได้มีตัวเองรักษาวงจรที่selfยังคงรักษาhelloWorldTimerและยังคงรักษาhelloWorldTimer self
                    หากกำหนดเป้าหมาย iOS เวอร์ชัน 10 ขึ้นไปคุณสามารถใช้การแสดงผลแบบบล็อกTimerซึ่งช่วยลดความซับซ้อนของวงจรอ้างอิงที่อาจเกิดขึ้นได้เช่น:
weak var timer: Timer?
func startTimer() {
    timer?.invalidate()   // just in case you had existing `Timer`, `invalidate` it before we lose our reference to it
    timer = Timer.scheduledTimer(withTimeInterval: 60.0, repeats: true) { [weak self] _ in
        // do something here
    }
}
func stopTimer() {
    timer?.invalidate()
}
// if appropriate, make sure to stop your timer in `deinit`
deinit {
    stopTimer()
}แม้ว่าTimerโดยทั่วไปจะดีที่สุด แต่เพื่อความสมบูรณ์ แต่ฉันควรทราบว่าคุณสามารถใช้ตัวจับเวลาการจัดส่งซึ่งมีประโยชน์สำหรับการตั้งเวลาตัวจับเวลาบนเธรดพื้นหลัง ด้วยตัวจับเวลาการจัดส่งเนื่องจากเป็นแบบบล็อกจึงหลีกเลี่ยงความท้าทายของวัฏจักรการอ้างอิงที่มีรูปแบบเก่าtarget/ selectorรูปแบบTimerตราบเท่าที่คุณใช้weakการอ้างอิง
ดังนั้น:
var timer: DispatchSourceTimer?
func startTimer() {
    let queue = DispatchQueue(label: "com.domain.app.timer")  // you can also use `DispatchQueue.main`, if you want
    timer = DispatchSource.makeTimerSource(queue: queue)
    timer!.schedule(deadline: .now(), repeating: .seconds(60))
    timer!.setEventHandler { [weak self] in
        // do whatever you want here
    }
    timer!.resume()
}
func stopTimer() {
    timer?.cancel()
    timer = nil
}
deinit {
    self.stopTimer()
}สำหรับข้อมูลเพิ่มเติมโปรดดูการสร้างตัวจับเวลาของตัวอย่างแหล่งที่มาของการจัดส่งในส่วนแหล่งที่มาของการจัดส่งของคู่มือการเขียนโปรแกรมพร้อมกัน
dispatch_afterคุณต้องการใช้ NSTimerหรือไม่ใช่การทำซ้ำ
                    นี่คือการอัปเดตสำหรับNSTimerคำตอบสำหรับ Swift 3 (ซึ่งNSTimerถูกเปลี่ยนชื่อเป็นTimer) โดยใช้การปิดแทนที่จะเป็นฟังก์ชันที่มีชื่อ:
var timer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) {
    (_) in
    print("Hello world")
}หากคุณสามารถปล่อยให้ล่องลอยได้สักระยะหนึ่งนี่เป็นวิธีง่ายๆที่เรียกใช้โค้ดบางส่วนทุกนาที:
private func executeRepeatedly() {
    // put your code here
    DispatchQueue.main.asyncAfter(deadline: .now() + 60.0) { [weak self] in
        self?.executeRepeatedly()
    }
}เพียงเรียกใช้executeRepeatedly()ครั้งเดียวและจะดำเนินการทุกนาที การดำเนินการจะหยุดลงเมื่อปล่อยอ็อบเจ็กต์ที่เป็นเจ้าของ ( self) คุณยังสามารถใช้แฟล็กเพื่อระบุว่าการดำเนินการต้องหยุดลง
ใน Swift 3.0 GCD ได้รับการปรับโครงสร้างใหม่:
let timer : DispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
timer.scheduleRepeating(deadline: .now(), interval: .seconds(60))
timer.setEventHandler
{
    NSLog("Hello World")
}
timer.resume()สิ่งนี้มีประโยชน์อย่างยิ่งเมื่อคุณต้องการจัดส่งในคิวใดคิวหนึ่ง นอกจากนี้หากคุณวางแผนที่จะใช้สิ่งนี้สำหรับการอัปเดตอินเทอร์เฟซผู้ใช้ฉันขอแนะนำให้ดูCADisplayLinkเนื่องจากมันซิงโครไนซ์กับอัตราการรีเฟรช GPU