简体   繁体   English

Kotlin懒惰的用法

[英]Kotlin lazy usage

I'm currently using Realm in my application, and to make sure i manage Realm instances correctly, i introduced in my base Activity a variable like this: 我目前正在我的应用程序中使用Realm,为了确保我正确管理Realm实例,我在我的基本Activity中引入了一个这样的变量:

protected val realm: Realm by lazy {
        Realm.getDefaultInstance()
}

And then in onDestroy i do this: 然后在onDestroy中我这样做:

override fun onDestroy() {
    super.onDestroy()
    realm.close()
}

And then i realised this is a waste. 然后我意识到这是一种浪费。 If the current activity doesn't use realm, it will open and immediately close in onDestroy . 如果当前活动不使用领域,它将打开并立即关闭onDestroy

So i updated to this: 所以我更新到这个:

    private var usedRealm = false

    protected val realm: Realm by lazy {
        usedRealm = true
        Realm.getDefaultInstance()
    }

override fun onDestroy() {
        super.onDestroy()

        if (usedRealm) {
            realm.close()
        }
    }

Is there any way to accomplish the same, without the extra flag? 有没有办法完成同样的事情,没有额外的旗帜?

  1. There is a bug in your current implementation. 您当前的实施中存在一个错误。 If Realm.getDefaultInstance() throws then usedRealm will be set to true but the lazy won't actually be initialized (intialization would have failed). 如果抛出Realm.getDefaultInstance()那么usedRealm将被设置为true但实际上不会初始化lazy(初始化将失败)。 You can fix this by only calling usedRealm = true after calling Realm.getDefaultInstance() : 您可以通过调用Realm.getDefaultInstance() 之后仅调用usedRealm = true来解决此问题:

     protected val realm: Realm by lazy { val realm = Realm.getDefaultInstance() usedRealm = true realm } 

    or 要么

     protected val realm: Realm by lazy { Realm.getDefaultInstance().apply { usedRealm = true } } 
  2. You can accomplish the same without the extra flag by keeping a reference to the raw Lazy object itself: 通过保持对原始Lazy对象本身的引用,您可以在没有额外标志的情况下完成相同的操作:

     private val lazyRealm = lazy { Realm.getDefaultInstance() } protected val realm by lazyRealm override fun onDestroy() { super.onDestroy() if (lazyRealm.isInitialized()) { realm.close() } } 

    This still requires an additional field but you no longer have to maintain the initialization state yourself. 这仍然需要一个额外的字段,但您不必再自己维护初始化状态。

  3. You can also use Lazy directly instead of as a delegate : 您也可以直接使用Lazy而不是委托

     protected val lazyRealm = lazy { Realm.getDefaultInstance() } override fun onDestroy() { super.onDestroy() if (lazyRealm.isInitialized()) { lazyRealm.value.close() } } 

    or 要么

     protected val lazyRealm = lazy { Realm.getDefaultInstance() } override fun onDestroy() { super.onDestroy() with(lazyRealm) { if (isInitialized()) { value.close() } } } 

    This makes it so that there is no extra property but Lazy is now part of your API and everywhere where you would have simply referenced realm you now have to reference lazyRealm.value . 这使得它没有额外的属性,但是Lazy现在是你的API的一部分,并且在任何你只想引用它的realm你现在必须引用lazyRealm.value You get to weigh the pros and cons. 你要权衡利弊。 :-) :-)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM