使用Timer在参考周期中强,弱或无主

问题描述 投票:1回答:2

我有一个UIViewController,它引用了一个反复调用闭包的Timer对象。 Timer对象在其区块中捕获self。据我所知,这导致视图控制器和块之间的retains cycle。有一个逻辑将计时器设置为nil,然后保留周期被中断,但可能无法执行。

我的问题如下:只要应用程序存在,View Controller就会存在(至少在当前实现中)。在这种情况下 - 我应该如何最好地处理这个保留周期?我应该忽略它,因为View控制器无论如何都不会被释放。我应该考虑可能的未来变化,并使用unownedweak参考和哪一个处理它。我想它应该是unowned,因为定时器只由View Controller保留,一旦View Controller被释放就应该释放,但不确定我是否遗漏了什么。先感谢您。以下代码是我所说的简单示例。 Class A是View Controller。

class A {

    var timer: Timer? = nil
    var varToReference: Int = 0

    func startTimer() {
        timer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true, block: {  (theTimer) in

            self.varToReference += 1

        })
    }

    func stopTimer() {
        if let theTimer = timer {
            theTimer.invalidate()
            timer = nil
        }
    }

    func onAdapterStarts() {
        self.startTimer()
    }

    func onAdapterStops(){
        self.stopTimer()
    }

    deinit {
        print("A Deinit")
    }

}
ios swift memory-leaks closures reference-cycle
2个回答
1
投票

保留周期是两个对象保持对彼此的引用并被保留的条件,它创建一个循环,因为两个对象都试图相互保留。

现在让我们来看看你的示例代码

在你的例子中,Class A通过timer变量拥有闭包。如果你没有将self声明为weakunowned,那么闭包也会拥有self,从而创建一个强大的参考周期。

unownedweak之间的区别

unownedweak之间的一个简单区别是weak被宣布为可选的,而unowned则不是。通过声明它weak你可以处理在某些时候它在闭包内可能是零的情况。如果你试图访问恰好是nil的unowned变量,它将导致整个程序崩溃。因此,只有当你肯定变量将永远存在于闭包附近时才使用unowned

始终准备好功能,因为您在任何移动应用中的工作都应该始终可扩展。

See this accepted answer for better understanding.


2
投票

在你的情况下,weakunowned是可以接受的。使用定时器块内的简单代码我建议使用weak,otherwice,你可以更喜欢unowned。使用weak关注项目的未来更新和扩展。

timer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true, block: {[weak self] (theTimer) in

        self?.varToReference += 1

    })
© www.soinside.com 2019 - 2024. All rights reserved.