将self分配为委托实现会导致内存泄漏吗?

时间:2019-04-17 08:32:28

标签: swift

您好,我有2个协议,第二个具有和第一个协议类型的引用,并且它为该引用返回self。这是代码。

protocol MainViewModelInput {
    func loginButtonAction()
    func registerButtonAction()
}

protocol MainViewModelProvider {
    var input: MainViewModelInput { get }
}

extension MainViewModelProvider where Self: MainViewModelInput {
    var input: MainViewModelInput { return self }
}

所以当我像这样实现它时,会不会造成内存泄漏?

class MainViewModel: MainViewModelProvider, MainViewModelInput {

    private let router: AnyRouter<MainRoute>

    init(router: AnyRouter<MainRoute>) {
        self.router = router
    }
}

extension MainViewModel {

    func loginButtonAction() {
        router.trigger(.login)
    }

    func registerButtonAction() {
        router.trigger(.register)
    }
}

我的想法是,如果MainViewController创建类型为MainViewModel的对象,并且input也持有对该对象的引用,那么它将永远不会被释放,我错了吗?

谢谢。

2 个答案:

答案 0 :(得分:1)

通常,您希望您的委托人成为weak var以避免在您这样的情况下的保留周期-这就是在UIKit类(例如UITableView)中实现委托模式的方式

在您的情况下,您将input变量定义为仅获取的计算属性。 Swift中的计算属性就像一个函数一样工作-它们不存储任何内容,它们只是提供一种间接检索某些值的方法。

可能可行,但是,您需要格外小心。一个例子:让我们修改代码,就像这样:

class MainViewModel: MainViewModelProvider, MainViewModelInput {

    private let router: AnyRouter<MainRoute>

    var input: MainViewModelInput?

    init(router: AnyRouter<MainRoute>) {
        self.router = router

        input = self
    }
}

我们做了什么:我们已经覆盖了input属性的默认实现-它不再是计算属性。而且我们还引入了内存泄漏-现在self对自身拥有强大的参考。

因此,通常来说:您的想法可能可行,但前提是您要格外小心,不要覆盖input属性来存储和引用self

答案 1 :(得分:0)

我要做的是创建一个检查self是否为MainViewModelInput的函数。

if let modelInput = self as? MainViewModelInput {
    // Here you should have access to protocol implementation
}