Kotlin懒惰的用法

时间:2016-08-05 17:07:15

标签: android realm kotlin

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

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

然后在onDestroy中我这样做:

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

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

所以我更新到了这个:

    private var usedRealm = false

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

override fun onDestroy() {
        super.onDestroy()

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

有没有办法实现同样的目标,没有额外的旗帜?

1 个答案:

答案 0 :(得分:14)

  1. 您当前的实施中存在错误。如果Realm.getDefaultInstance()抛出,则usedRealm将设置为true,但实际上不会初始化延迟(初始化将失败)。您只需在调用usedRealm = true后调用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 }
    }
    
  2. 通过保持对原始Lazy对象本身的引用,您可以在没有额外标志的情况下完成相同的操作:

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

    这仍然需要一个额外的字段,但您不必再自己维护初始化状态。

  3. 您也可以直接使用Lazy代替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。你要权衡利弊。 : - )