Kotlin 推荐的使用 SAM 注销监听器的方法

Kotlin recommended way of unregistering a listener with a SAM

所以我有一个交互器,它使用 Realm 执行插入操作,然后使用 RealChangeListener 通知插入完成。它是这样的:

fun insertCar(item: Car) {
        realm.doInTransaction {
            val car = Car(...)
            val copy = copyToRealm(car)
            copy.addChangeListener(...)
        }
    }

我可以这样做:

fun insertCar(item: Car, listener: RealmChangeListener<Car>) {
            realm.doInTransaction {
                val car = Car(...)
                val copy = copyToRealm(car)
                copy.addChangeListener(listener)
            }
        }

并像这样访问:

realmInteractor.insertCar(item, RealmChangeListener {
   // do something here
})

但是我没有办法删除这个监听器

realmInteractor.insertCar(item, RealmChangeListener {
   // do something here
   it.removeChangeListener(this)
})

this 将指向 class 它所在的位置而不是实际的侦听器

我也可以这样做:

fun insertCar(item: Car, doAfterChange (Car) -> Unit) {
                realm.doInTransaction {
                    val car = Car(...)
                    val copy = copyToRealm(car)
                    copy.addChangeListener(RealmChangeListener{
                    doAfterChange()
                    })
                }
            }

但是我在另一个 SAM 中有一个 SAM(在我看来太过分了)

我可以这样做:

fun insertCar(item: Car, listener: RealmChangeListener<Car>) {
                realm.doInTransaction {
                    val car = Car(...)
                    val copy = copyToRealm(car)
                    copy.addChangeListener(listener)
                }
            }

realmInteractor.insertCar(item, object : RealmChangeListener<Car> {
                        override fun onChange(element: Car?) {
                            ...
                            element?.removeChangeListener(this)
                        }
                    })

哪个有效,但太冗长了。

那么你如何处理这个问题,什么是最好的方法?

您可以创建一个通用方法来执行 运行-一次侦听器。大致如下:

fun <T> createInRealm(objectFactory: () -> T, changeListener: (T) -> Unit) {
    realm.doInTransaction {
         val obj = objectFactory()
         val copy = copyToRealm(obj)
         copy.addChangeListener(object : RealmChangeListener<T> {
             override fun onChange(element: T) {
                 changeListener()
                 element.removeChangeListener(this)
             }
         }
    }
}