Cómo establecer la propiedad de Kotlin tardía en nulo

La class de abajo tiene un ciclo de vida muy único, que me obliga a lateinit temporalmente las properties lateinit

 class SalesController : BaseController, SalesView { @Inject lateinit var viewBinder: SalesController.ViewBinder @Inject lateinit var renderer: SalesRenderer @Inject lateinit var presenter: SalesPresenter lateinit private var component: SalesScreenComponent override var state = SalesScreen.State.INITIAL //only property that I want to survive config changes fun onCreateView(): View { /** lateinit variables are set here */ } fun onDestroyView() { //lateinit variables need to be dereferences here, or we have a memory leak renderer = null!! //here's the problem: throws exception bc it's a non-nullable property 

}}

Así es como lo usa el marco.

 controller.onCreateView() //same instance of controller controller.onDestroyView() //same instance of controller controller.onCreateView() //same instance of controller controller.onDestroyView() //same instance of controller 

Mis properties lateinit se inyectan con daga, y debo configurarlas para que onDestroyView en onDestroyView , o tener una pérdida de memory. Sin embargo, esto no es posible en kotlin, hasta donde yo sé (sin reflexión). Podría hacer que estas properties sean nulables, pero eso vencería el propósito de la security nula de Kotlin.

No estoy muy seguro de cómo resolver esto. ¿Idealmente podría haber algún tipo de procesador de anotación que generaría código java para onDestroyView variables específicas automáticamente en onDestroyView ?

lateinit properties de lateinit usan null como un valor de indicador no inicializado, y no existe una manera clara de establecer null en el campo de respaldo de una propiedad de lateinit sin reflexión.


Sin embargo, Kotlin le permite anular el comportamiento de las properties usando properties delegadas. Parece que no hay ningún delegado que permita eso en kotlin-stdlib , pero si necesita exactamente este comportamiento, puede implementar su propio delegado para hacerlo, agregando algún código a sus utilidades:

 class ResettableManager { private val delegates = mutableListOf<ResettableNotNullDelegate<*, *>>() fun register(delegate: ResettableNotNullDelegate<*, *>) { delegates.add(delegate) } fun reset() { delegatesToReset.forEach { it.reset() } } } class Resettable<R, T : Any>(manager: ResettableManager) { init { manager.register(this) } private var value: T? = null operator fun getValue(thisRef: R, property: KProperty<*>): T = value ?: throw UninitializedPropertyAccessException() operator fun setValue(thisRef: R, property: KProperty<*>, t: T) { value = t } fun reset() { value = null } } 

Y el uso:

 class SalesController : BaseController, SalesView { val resettableManager = ResettableManager() @set:Inject var viewBinder: SalesController.ViewBinder by Resettable(resettableManager) @set:Inject var renderer: SalesRenderer by Resettable(resettableManager) @set:Inject var presenter: SalesPresenter by Resettable(resettableManager) fun onDestroyView() { resettableManager.reset() } } 

Creo que lo que necesitas es una propiedad normal que permita el nullable y saludable sin la madurez de lo lateinit :

 class SalesController : BaseController, SalesView { @Inject @JvmField var viewBinder: SalesController.ViewBinder? = null 

Con esta solución, el comstackdor le pedirá que verifique si viewBinder es null o no, pero IMO es apropiado aquí ya que puede ser null en cualquier punto de su progtwig.

  • Kotlin null-check error
  • Cómo implementar lateinit correctamente con objects de class personalizados para usar en onCreate () en Android evitando el error 'Property getter or setter expected'
  • Asignación variable de nula Kotlin
  • ¿Qué es el doble explosión de Kotlin?
  • Kotlin security nula?
  • Lanzamiento inteligente a kotlin.String
  • Kotlin con si no es nulo
  • Conversor de Java a Kotlin y arguments de método nulable
  • ¿Kotlin no se puede anular valor puede ser nulo?
  • Cómo hacer comprobaciones nulas con las funciones de extensión de Kotlin en una actividad de Android
  • Kotlin comtesting null dos veces en caso de que no