iOS开发:如何在其他ViewController中停止homeview中运行的Timer
多ViewController场景下Timer停止的实现方案
前置注意事项
首先需要确保homeView中的Timer是类的全局存储属性,不能是方法内的局部变量,否则无法调用invalidate()方法停止,正确声明示例:
// homeView类内声明 var autoLoadTimer: Timer? // 初始化Timer的代码 autoLoadTimer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(loadData), userInfo: nil, repeats: true)
可选实现方案
方案1:使用NotificationCenter发送跨页面通知
适合多页面都需要监听登出事件的场景:
- 在homeView的
viewDidLoad方法中添加通知观察者,监听登出事件:
NotificationCenter.default.addObserver(self, selector: #selector(stopAutoLoadTimer), name: NSNotification.Name("userDidLogout"), object: nil) // 实现停止Timer的方法 @objc func stopAutoLoadTimer() { autoLoadTimer?.invalidate() autoLoadTimer = nil }
- 在menuView的登出按钮点击逻辑中,先发送登出通知,再执行返回loginView的跳转:
NotificationCenter.default.post(name: NSNotification.Name("userDidLogout"), object: nil) // 后续执行返回loginView的代码
方案2:使用闭包回调传递停止事件
适合层级简单、只有两个关联页面的场景:
- 在
menuSetupViewController类内定义回调闭包属性:
var logoutCallback: (() -> Void)?
- 在homeView跳转menuView的代码中,给闭包赋值停止Timer的逻辑:
let storyBoard: UIStoryboard = UIStoryboard(name: "mapFirstPage", bundle: nil) let newViewController = storyBoard.instantiateViewController(withIdentifier: "menuSetupVC") as! menuSetupViewController newViewController.modalPresentationStyle = .fullScreen // 新增闭包赋值逻辑 newViewController.logoutCallback = { [weak self] in self?.autoLoadTimer?.invalidate() self?.autoLoadTimer = nil } self.navigationController?.pushViewController(newViewController, animated: true)
- 在menuView的登出按钮点击逻辑中,先调用闭包再跳转:
logoutCallback?() // 后续执行返回loginView的代码
方案3:封装全局Timer管理单例
如果App中存在多个页面的定时任务,建议封装统一的Timer管理器,统一管控所有Timer的启动、停止、销毁,避免出现无效Timer后台运行、内存泄漏等问题。
内容的提问来源于stack exchange,提问作者user16104694
相关产品推荐
相关产品推荐

