// // 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 UIKitclass SecondaryViewController: UIViewController {var timer: DispatchSourceTimer?var count = 0override func viewDidLoad() {super.viewDidLoad()title = "测试DispatchTime"view.backgroundColor = .whiteaddNoti()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] inself?.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 += 1print(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()}}