查看具有强引用的控制器导致内存泄漏

时间:2016-12-13 17:59:56

标签: ios swift swift2 red5 strong-references

我的一个视图控制器中存在强引用问题导致内存泄漏。首先,我的设置:

2个视图控制器(v1和v2)。 v1转向v2,v2有一个关闭按钮,自动回弹到v1。 v2包含尝试无限重新连接的代码,直到建立连接。 (使用red5pro的视频流)。这是代码:

func reconnect(){
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(5.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { () -> Void in
            self.connectToStream()
        }
}

在我的情况下,连续重新连接是可取的,但是当用户退出v2时,我希望重新连接停止。但是目前,即使用户离开v2,重新连接也会无限进行。

我已经知道这是因为v2具有强大的引用并且即使在用户退出之后仍然继续存在。所以这导致无限调用reconnect()方法的代码继续运行。我将尝试清理v2以将所有内容转换为弱引用,但我也在考虑一些替代方案,并且我有几个问题:

  1. 有没有办法杀死viewDidDisappear上的重新连接,所以即使我的视图控制器没有被破坏,至少我的重新连接过程会停止?

  2. 从v2退回到v1后,如果用户再次转到v2,是否可以分配相同的v2实例,而不是每次都创建一个新实例?

1 个答案:

答案 0 :(得分:3)

dispatch_after无法取消,但有几个选项:

  1. 使用弱引用,这将允许self被释放:

    func reconnect() {
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(5.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { [weak self] in
            self?.connectToStream()
        }
    }
    

    这无疑会使计时器继续运行,但会阻止其保留视图控制器,因此视图控制器将被释放并且不会调用connectToStream

  2. 使用NSTimer并在视图消失时取消:

    weak var timer: NSTimer?
    
    func reconnect() {
        timer?.invalidate()
        timer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: #selector(handleTimer(_:)), userInfo: nil, repeats: false)
    }
    
    func handleTimer(timer: NSTimer) {
        self.connectToStream()
    }
    
    override func viewDidDisappear() {
        super.viewDidDisappear()
        timer?.invalidate()
    }
    

    注意,因为这个基于selector的{​​{1}}保留了对其NSTimer的强引用,所以您无法在target中取消(因为有一个强大的参考周期)。因此,您必须找到一些其他适当的事件来解决此问题(例如deinit)。