1

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

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 实例而不是每次都创建一个新实例?

4

1 回答 1

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()
    }
    

    请注意,因为 this selector-basedNSTimer保持对其的强引用target,所以您不能取消deinit(因为存在强引用循环)。所以你必须找到一些其他合适的事件来解决这个问题(例如viewDidDisappear)。

于 2016-12-13T18:48:21.563 回答