我的一个视图控制器中存在强引用问题导致内存泄漏。首先,我的设置:
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以将所有内容转换为弱引用,但我也在考虑一些替代方案,并且我有几个问题:
有没有办法杀死viewDidDisappear上的重新连接,所以即使我的视图控制器没有被破坏,至少我的重新连接过程会停止?
从v2退回到v1后,如果用户再次转到v2,是否可以分配相同的v2实例,而不是每次都创建一个新实例?
答案 0 :(得分:3)
dispatch_after
无法取消,但有几个选项:
使用弱引用,这将允许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
。
使用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
)。