Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> iOS

วิธีทำงานซ้ำ (Repeat Task) ทุกช่วงเวลาที่กำหนดใน Swift/iOS

รันงานซ้ำๆ ทุกๆ นาที/วินาที ด้วย Timer ใน iOS

ใช้ Timer.scheduledTimer กำหนด Interval และ Repeats = true

ขั้นตอนที่ 1: สร้างโปรเจกต์

Xcode → Single View App → ชื่อ "Timer"

ขั้นตอนที่ 2: เพิ่ม Label ใน Storyboard

สำหรับแสดงเวลาที่ผ่านไป

ขั้นตอนที่ 3: IBOutlet และ Variables

@IBOutlet weak var timerLabel: UILabel!

var timeLaunched: Int = 0
var timer: Timer?

ขั้นตอนที่ 4: ฟังก์ชันอัปเดต Label

@objc func updateLabel() {
    timerLabel.text = "Time Launched = \(timeLaunched) Seconds"
    timeLaunched += 1
}

ขั้นตอนที่ 5: เริ่ม Timer ใน viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()
    
    updateLabel() // แสดงค่าเริ่มต้นทันที
    
    timer = Timer.scheduledTimer(
        timeInterval: 1.0,      // ทุก 1 วินาที
        target: self,
        selector: #selector(updateLabel),
        userInfo: nil,
        repeats: true           // true = ทำซ้ำ, false = ครั้งเดียว
    )
}

ขั้นตอนที่ 6: หยุด Timer (สำคัญ!)

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    timer?.invalidate() // หยุด Timer
    timer = nil         // ปล่อย Reference
}

รันโปรเจกต์

Label จะนับขึ้นทุกวินาที: 0, 1, 2, 3... จนกว่าจะปิดหน้าจอ


วิธีทันสมัย: DispatchSourceTimer (Precision & Background)

let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
timer.schedule(deadline: .now(), repeating: 1.0)
timer.setEventHandler {
    // Background work here
    DispatchQueue.main.async {
        self.updateLabel()
    }
}
timer.resume()

// หยุด:
timer.cancel()

Swift 5.5+ Async/Await Loop

func startPeriodicUpdates() {
    Task {
        while !Task.isCancelled {
            try? await Task.sleep(nanoseconds: 1_000_000_000) // 1 วินาที
            await MainActor.run { self.updateLabel() }
        }
    }
}

สรุปการเลือก

APIเหมาะสำหรับPrecisionBackground
TimerUI Updates, Simple~10-50ms❌ (Main Thread)
DispatchSourceTimerHigh Precision, Background~1ms✅
Task.sleep LoopModern Swift ConcurrencyGood✅ (Structured Concurrency)

⚠️ ข้อควรระวัง

  • Timer จะ Retain Target → ต้อง invalidate() และ nil-out
  • ใช้ weak self ใน Closure เพื่อป้องกัน Retain Cycle
  • Background Timer อาจถูก Throttle บน iOS (ประหยัดแบต)