//
// SecondaryViewController.swift
// 0401
//
// Created by kqc on 2025/7/30.
//
/*
* 使用DispatchSourceTimer注意点
* 1: suspend状态不能调用cancel方法会崩溃
* 2: 重复调用resume或者suspend方法崩溃,必须成对出现
* 3: 销毁时如果 resume() -> cancel() -> time = nil 会在特定机型崩溃偶发频率很高 如iPhone13,iPhone16等
* 针对3的修改,在setCancelHandler中执行对应的销毁操作
*/
import UIKit
class SecondaryViewController: UIViewController {
var timer: DispatchSourceTimer?
var count = 0
override func viewDidLoad() {
super.viewDidLoad()
title = "测试DispatchTime"
view.backgroundColor = .white
addNoti()
createTimer()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
timer?.suspend()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
timer?.resume()
}
func createTimer() {
timer = DispatchSource.makeTimerSource()
timer?.schedule(deadline: .now(), repeating: .seconds(2), leeway: .milliseconds(100))
timer?.setEventHandler(handler: DispatchWorkItem(block: {
print("测试数据...")
}))
// To safely close a file descriptor or destroy a Mach port, a cancellation handler is required for that descriptor or port.
timer?.setCancelHandler(handler: DispatchWorkItem(block: {[weak self] in
self?.timer = nil
}))
}
func stopTimer() {
guard let timer = timer else {
return
}
timer.suspend()
}
func recoverTimer() {
guard let timer = timer else {
return
}
timer.resume()
}
func closeTimer() {
timer?.resume()
timer?.cancel()
// self.timer = nil
}
func delayAction() {
DispatchQueue.main.asyncAfter(deadline: .now() + 1){
self.count += 1
print(self.count)
}
}
deinit {
closeTimer()
removeNoti()
debugPrint("销毁")
}
}
extension SecondaryViewController {
func addNoti() {
NotificationCenter.default.addObserver(self, selector: #selector(becomeActiveStatu), name: UIApplication.willEnterForegroundNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(resignActiveStatu), name: UIApplication.willResignActiveNotification, object: nil)
}
func removeNoti() {
NotificationCenter.default.removeObserver(self)
}
@objc func becomeActiveStatu() {
recoverTimer()
}
@objc func resignActiveStatu() {
stopTimer()
}
}