美文网首页
1期_Swift中Timer的使用

1期_Swift中Timer的使用

作者: 萧修 | 来源:发表于2023-12-20 15:22 被阅读0次

    Timer的使用经常伴随着循环引用问题。本文主要如何使用以及解决循环引用

    • Timer中iOS10前后区别
    • Timer那种Api需要加入当前RunLoop

    Timer改为局部变量,也会存在循环问题。就算使用scheduledTimer方法,内部默认添加到当前默认runloop中。也避免不了。更何况调用invalidate方法,进行定时的销毁

    RunLoop会强持有timer。Timer持有控制器。Runloop在程序运行期间不会销毁,timer就不会自动销毁,那么Timer引用的target也不会销毁

    func initScheduleTimer() {
    //已经添加到runloop中,但仍旧有循环引用问题
    let lineTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateLineTime), userInfo: nil, repeats: true)
    
    }
    

    Timer中前四种方法不推荐使用,都有循环引用问题.
    iOS10之后增加了Timer的block形式,内部是没有循环引用问题,在iOS10之前存在。

    使用init(timeInterval:等方法创建的Timer需要加入RunLoop中;使用scheduledTimer创建的Timer内部会自动添加

    open class Timer : NSObject {
        
        //不推荐使用
        public /*not inherited*/ init(timeInterval ti: TimeInterval, invocation: NSInvocation, repeats yesOrNo: Bool)
    
        //不推荐使用
        open class func scheduledTimer(timeInterval ti: TimeInterval, invocation: NSInvocation, repeats yesOrNo: Bool) -> Timer
    
        //不推荐使用
        public /*not inherited*/ init(timeInterval ti: TimeInterval, target aTarget: Any, selector aSelector: Selector, userInfo: Any?, repeats yesOrNo: Bool)
    
        //不推荐使用
        open class func scheduledTimer(timeInterval ti: TimeInterval, target aTarget: Any, selector aSelector: Selector, userInfo: Any?, repeats yesOrNo: Bool) -> Timer
        
        
        @available(iOS 10.0, *)
        public /*not inherited*/ init(timeInterval interval: TimeInterval, repeats: Bool, block: @escaping @Sendable (Timer) -> Void)
    
        
        /// 
        @available(iOS 10.0, *)
        open class func scheduledTimer(withTimeInterval interval: TimeInterval, repeats: Bool, block: @escaping @Sendable (Timer) -> Void) -> Timer
    }
    

    iOS10之前解决循环引用

    • 建立中间类SwiftWeakProxy
    func initProxyTimer() {
        let pro = SwiftWeakProxy(self)
        lineTimer = Timer.scheduledTimer(timeInterval: 1.0, target: pro, selector: #selector(updateLineTime), userInfo: nil, repeats: true)
    }
    
    class SwiftWeakProxy: NSObject {
        weak var target:NSObjectProtocol?
        public init(_ target:NSObjectProtocol?) {
            super.init()
            self.target = target
        }
        override func forwardingTarget(for aSelector: Selector!) -> Any? {
            if self.target?.responds(to: aSelector) == true {
                return self.target
            } else {
                return super.forwardingTarget(for: aSelector)
            }
        }
        
        deinit {
            print("\(self)-deinit")
        }
    }
    
    
    • Timer扩展
    extension Timer {
        
        /// Timer将userInfo作为callback的定时方法
        /// 目的是为了防止Timer导致的内存泄露
        /// - Parameters:
        ///   - timeInterval: 时间间隔
        ///   - repeats: 是否重复
        ///   - callback: 回调方法
        /// - Returns: Timer
        public static func zk_scheduledTimer(timeInterval: TimeInterval, repeats: Bool, with callback: @escaping () -> Void) -> Timer {
            return scheduledTimer(timeInterval: timeInterval,
                                  target: self,
                                  selector: #selector(callbackInvoke(_:)),
                                  userInfo: callback,
                                  repeats: repeats)
        }
        
        /// 私有的定时器实现方法
        ///
        /// - Parameter timer: 定时器
        @objc
        private static func callbackInvoke(_ timer: Timer) {
            guard let callback = timer.userInfo as? () -> Void else { 
                print("未实现timer.userInfo方法")
                return
            }
            callback()
        }
        
    }
    

    调用方法

    func initextensionTimer()  {
            lineTimer = Timer.zk_scheduledTimer(timeInterval: 1.0, repeats: true, with: { [weak self]  in
                guard let `self` = self else { return }
                self.updateLineTime()
            })
        }
    

    相关文章

      网友评论

          本文标题:1期_Swift中Timer的使用

          本文链接:https://www.haomeiwen.com/subject/cjotndtx.html