计时器的参考周期中强,弱或无主

时间:2019-04-25 09:13:00

标签: ios swift memory-leaks closures reference-cycle

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

我的问题如下:View Controller的寿命将与该应用程序的生存时间一样长(至少在当前实施中)。在这种情况下-我该如何最好地注意这个保留周期?我应该忽略它,因为无论如何不会释放View控制器。我应该考虑将来可能发生的更改,并使用unownedweak引用以及哪个引用来处理。我猜应该是unowned,因为计时器仅由View Controller保留,并且应该在View Controller释放后才释放,但不确定是否丢失了某些东西。先感谢您。以下代码是我正在谈论的简单示例。 Class A是视图控制器。

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

}

2 个答案:

答案 0 :(得分:2)

在您的情况下,weakunowned是可以接受的。建议在定时器块中使用简单的代码,否则建议您使用weakunowned。使用weak来关心项目的将来更新和扩展。

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

        self?.varToReference += 1

    })

答案 1 :(得分:1)

  

保留周期是两个对象相互引用并被保留的条件,由于两个对象都试图互保留,因此创建了一个周期。

现在让我们看一下示例代码

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

unownedweak之间的差异

unownedweak之间的一个简单区别是weak被声明为可选,而unowned则不是。通过将其声明为weak,您可以处理在封闭点内可能 nil 的情况。如果您尝试访问恰好为 nil unowned变量,它将崩溃整个程序。因此,仅当您肯定变量在闭包周围时将始终存在时,才使用unowned

  

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

See this accepted answer for better understanding.