iOS NSTimer 的循环引用问题

话不多说直接上重点,先看 Timer 初始化:

//
//  ViewController.swift
//  计时器
//
//  Created by 张闯 on 2018/12/12.
//  Copyright © 2018 Rotai. All rights reserved.
//

import UIKit


class ViewController: UIViewController {

    var timer: Timer?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(timerAction), userInfo: nil, repeats: true)
        
    }

    
    @objc func timerAction() -> Void {
        print("timer 测试方法")
    }
    
    deinit {
        timer?.invalidate()
    }
    

}

这是一段 Timer 初始化的方法,但是这种使用方式会造成 retain cycle! 原因如下:

// self.timer    self -> Timer 强引用
// target: self  Timer -> self 强引用

要知道,打破 retain cycle 的方式必须有一个引用是弱引用,掌握这个点就好,下面用两种方式解决此问题.

一. 使用 Timer 的 block 方法

在 block 内部对 viewController 为弱引用,从而打破 retain cycle

         //self.timer    self -> Timer 强引用
         //block         block --> self 弱引用
        timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { [weak self] (timer)  in
            self?.timerAction()
        })

二. 使用代理对象

class TimerProxy: NSObject {
    
    weak var target: AnyObject?
    
    init(_ target: AnyObject) {
        self.target = target
    }
    
    override func forwardingTarget(for aSelector: Selector!) -> Any? {
        return self.target
    }
    
}
//2.利用其它类作为 target,
        timer = Timer.scheduledTimer(timeInterval: 1, target: TimerProxy(self), selector: #selector(timerAction), userInfo: nil, repeats: true)

实现思路如下:

// self -> timer        强引用
// timer -> newClass    强引用
// newClass --> self    弱引用

这里 TimerProxy 里会用到消息转发技术,其实最优的处理方案是生成 NSProxy 子类,这样会省去在方法列表查找方法的过程!

以上是两种解决 timer 循环引用的方法!希望对各位有所帮助!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值