如何在Swift中删除一个懒惰变量?

时间:2015-10-14 20:32:30

标签: ios swift swift2

我最近一直在阅读关于Swift initilization的一堆信息,一个似乎有一些优点的解决方案是利用惰性变量来避免选项的厄运和沮丧,特别是在扩展UIViewControllers或其他时候这些课程。考虑到这一点,我有类似的代码:

final class MyViewController : UIViewController {
    lazy private var myOtherViewController: MyOtherViewController = MyOtherViewController()

    deinit {
        // myOtherViewController = nil // Can't do this. Expression resolves to an unused l-value
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        myOtherViewController.foo();
    }
}

// elsewhere...
final class MyOtherViewController : UIViewController {
    deinit {
        print("Deinit!")
    }
}

在此示例中显示 MyOtherViewController的{​​{1}}方法似乎永远不会触发,但我也无法让deinit删除。不允许将其设置为myOtherViewController。是否有一些我错过的强迫nil保留的东西?或者我对垃圾收集器感到不耐烦?

2 个答案:

答案 0 :(得分:4)

要做到这一点,你的懒惰变量必须被声明为可选,即使你想要在需要值时(即懒惰地)初始化它。

class MyObject {

    func run() {
        print( "MyObject :: run()" )
    }

    init() {
        print( "MyObject :: init" )
    }

    deinit {
        print( "MyObject :: deinit" )
    }
}

class MyContext {
    lazy var myObject:MyObject? = MyObject()
}

let myContext = MyContext()
myContext.myObject?.run()   //< "MyObject :: init"
myContext.myObject = nil    //< "MyObject :: deinit"

另外,我不同意选择权的悲观和悲观的概念 - 只需要知道许多可用技术中哪一种最方便实用地处理它们,以及如何避免允许在给定上下文中,可选和非可选值的组合中存在许多状态排列。此外,一个可选项实际上正是你想要的,因为你打算来使它无效。在你初始化它之前,使用一个可选的并不意味着值将是nil,而是在它的生命中的任何时刻都可以是nil,即使它是在声明或任何其他时间事先。如果避免选项对您来说确实具有高优先级,那么您必须退后一步并重新评估您的体系结构,以创建一种不再需要对值进行去初始化的情况。

答案 1 :(得分:2)

我同意Grimxn的观点,这种将该属性设置为nil的模式(因此需要使其成为可选项以便能够这样做)是不必要的。取消分配MyViewController后,它会自动释放其对MyOtherViewController的强引用。

您需要手动nil此属性的唯一时间是您必须解决强引用周期(如果您有这样的周期,则无法在deinit中解决此问题,而是viewDidDisappear或类似的事情。)

如果您没有看到其他视图控制器被取消分配,那么我建议找到强引用周期的来源并解决它。