2

我有一个对重复调用闭包的对象UIViewController的引用。对象在其块中Timer捕获Timerself据我了解,这导致retains cycle了视图控制器和块之间的关系。有一个逻辑是把定时器设置为nil,然后retain cycle被打破,但它可能不会被执行。

我的问题如下:只要应用程序存在,视图控制器就会存在(至少在当前实现中)。在这种情况下 - 我应该如何最好地处理这个保留周期?我应该忽略它,因为无论如何都不会释放视图控制器。我是否应该考虑未来可能发生的变化并使用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")
    }

}
4

2 回答 2

2

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

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

        self?.varToReference += 1

    })
于 2019-04-25T10:00:14.417 回答
2

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

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

在您的示例中,通过变量Class A拥有闭包。timer如果不声明selfweak或者unowned闭包也会自己self创建一个强引用循环。

unowned和之间的区别weak

一个简单的区别是unownedweakweak声明为可选,而 asunowned不是。通过声明它,weak您可以处理在某些时候它可能在闭包内为零的情况。如果您尝试访问unowned恰好为nil的变量,它将使整个程序崩溃。因此,仅unowned在您确定变量在关闭时始终存在时才使用

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

请参阅此已接受的答案以更好地理解。

于 2019-04-25T10:06:39.720 回答