Timer封装

这里运用中介者模式的思想,封装一个Timer,简化其他对象与timer的交互过程
创建中介者类RTimer

 var timer: Timer?
    weak var target: NSObjectProtocol?
    var sel: Selector?
    
    func scheduled(timeInterval ti: TimeInterval, target aTarget: Any, selector aSelector: Selector, userInfo: Any?, repeats yesOrNo: Bool) {
        
        self.target = aTarget as? NSObjectProtocol
        self.sel = aSelector
        
        timer = Timer(timeInterval: ti, target: self, selector: aSelector, userInfo: userInfo, repeats: yesOrNo)
        RunLoop.current.add(timer!, forMode: .common)
        
        guard self.target?.responds(to: self.sel!) == true else {
            return
        }
       //交换方法
        let method = class_getInstanceMethod(self.classForCoder, #selector(fire))
        class_replaceMethod(self.classForCoder, self.sel!, method_getImplementation(method!), method_getTypeEncoding(method!))
    }

     @objc func fire() {
        //执行target的sel方法,如果target被释放,则销毁timer
        if self.target?.perform(self.sel!) == nil {
            timer?.invalidate()
        }
    }

timer的使用

//VC:
  rTimer.scheduled(timeInterval: 1, target: self, selector: #selector(timerFire), userInfo: nil, repeats: true)

rTimer会随着当前VC对象的释放自动销毁,不会存在循环引用问题,也不用手动调用timer.invalidate()

补充
如果VC没有实现aSelector方法,程序就会直接崩溃,我们可以重写RTimer的forwardingTarget方法,利用消息转发机制在崩溃前输出一些信息

 override func forwardingTarget(for aSelector: Selector!) -> Any? {
        print(aSelector)
        if target?.responds(to: self.sel!) == true {
            return target
        }
        print("\(target)没有实现方法:\(NSStringFromSelector(aSelector))")
        return super.forwardingTarget(for: aSelector)
    }

你可能感兴趣的:(Timer封装)