Kotlin懒惰用法 [英] Kotlin lazy usage

查看:118
本文介绍了Kotlin懒惰用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我当前在我的应用程序中使用Realm,并且为了确保我正确地管理Realm实例,我在基本Activity中引入了这样的变量:

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:

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

然后在onDestroy中,我这样做:

And then in onDestroy i do this:

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

然后我意识到这是浪费.如果当前活动不使用领域,它将在onDestroy中打开并立即关闭.

And then i realised this is a waste. If the current activity doesn't use realm, it will open and immediately close in onDestroy.

所以我更新为:

    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. 您当前的实现中存在一个错误.如果Realm.getDefaultInstance()抛出,则usedRealm将被设置为true,但实际上不会初始化惰性对象(初始化会失败).您可以通过仅在调用Realm.getDefaultInstance()之后调用usedRealm = true 来解决此问题:

  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). You can fix this by only calling usedRealm = true after calling Realm.getDefaultInstance():

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

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

  • 通过保留对原始 Lazy 对象本身:

  • You can accomplish the same without the extra flag by keeping a reference to the raw Lazy object itself:

    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.

    您也可以直接使用Lazy代替作为委托:

    You can also use Lazy directly instead of as a delegate:

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

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

    这使得它没有额外的属性,但是Lazy现在已成为您API的一部分,并且在您只需引用realm的任何地方,您现在都必须引用lazyRealm.value.您可以权衡利弊. :-)

    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. You get to weigh the pros and cons. :-)

    这篇关于Kotlin懒惰用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆