Swift中支持iOS9不会造成循环引用的定时器(DispatchSourceTimer)

不会移除不掉timer造成内存泄漏的timer

  • 利用GCD实现定时器功能

利用GCD实现定时器功能

首先为什么我要选择用DispatchSourceTimer来实现定时器功能:
个人认为不是Timer控制器/视图 循环引用造成的释放不掉,而是timer对它的target是强引用造成的.为什么呢?
苹果提供的Timer是要添加到RunLoop上的,当前的RunLoop对定时器有一个强引用,而Timer对它的target也是一个强引用,如果想要释放Timer,必须要先调用timer.invalidate(),然后再去释放,这样可以解决绝大部分的循环引用造成的内存泄漏

  1. 实例化一个DispatchSourceTimer

private(set) lazy var timer: DispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: .main)

  1. 给定时器添加任务
//给定时器添加事件
        timer.schedule(deadline: .now(), repeating: 1, leeway: .milliseconds(1))
        timer.setEventHandler {
            self.recordCount -= 1
        }
  1. 开启定时器
timer.resume()

在倒计时的按钮中,添加了点击的回调,将当前的timer回传到控制器或者视图

typealias ClickCallBack = ((_ timer: DispatchSourceTimer) -> ())
/// 点击的回调
    var clickCallBack: ClickCallBack?

所以在控制器中就可以在视图即将消失的时候调用timer.cancel()

override func viewWillDisappear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        sourceTimer?.cancel()
    }
    

此时去析构函数里面验证,控制器是否出栈

deinit {
        print("控制器出栈")
    }

Demo地址gitHub:https://github.com/lausen34/countdownButton

你可能感兴趣的:(iOS开发/Swift)