Kotlin рекомендовал способ отмены регистрации слушателя с помощью 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 будет указывать на класс, в котором он находится, а не на фактического слушателя

Я также могу сделать это:

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)
                        }
                    })

Что работает, но слишком многословно.

Итак, как вы справляетесь с этим и что считается лучшим подходом?


person johnny_crq    schedule 28.06.2016    source источник


Ответы (1)


Вы можете создать общий метод для выполнения однократного прослушивания. Что-то вроде:

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)
             }
         }
    }
}
person yole    schedule 28.06.2016