그런데 Fragment에서 View Binding을 쓸 때는 메모리 누수가 일어날 수 있는 문제가 있습니다. 다음 그림을 보시면 Fragment 속의 View는 onDestroyView에서 파괴되고 생명주기가 종료되지만, 그 시점에서 Fragment는 여전히 유지되고 있는 것을 알 수 있습니다.
메모리 누수 대응법
_binding의 직접 해제
그래서 구글에서는 Fragment에서 View Binding을 적용할 때 다음과 같이 _binding 변수를 만들어 사용한 뒤 onDestroyView에서 해제해주는 구조를 공식 문서 에서 제안하고 있습니다.
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/packagecom.android.example.github.utilimportandroidx.fragment.app.Fragmentimportandroidx.lifecycle.DefaultLifecycleObserverimportandroidx.lifecycle.LifecycleOwnerimportandroidx.lifecycle.observeimportkotlin.properties.ReadWritePropertyimportkotlin.reflect.KProperty/**
* A lazy property that gets cleaned up when the fragment's view is destroyed.
*
* Accessing this variable while the fragment's view is destroyed will throw NPE.
*/classAutoClearedValue<T:Any>(valfragment:Fragment):ReadWriteProperty<Fragment,T>{privatevar_value:T?=nullinit{fragment.lifecycle.addObserver(object:DefaultLifecycleObserver{overridefunonCreate(owner:LifecycleOwner){fragment.viewLifecycleOwnerLiveData.observe(fragment){viewLifecycleOwner->viewLifecycleOwner?.lifecycle?.addObserver(object:DefaultLifecycleObserver{overridefunonDestroy(owner:LifecycleOwner){_value=null}})}}})}overridefungetValue(thisRef:Fragment,property:KProperty<*>):T{return_value?:throwIllegalStateException("should never call auto-cleared-value get when it might not be available")}overridefunsetValue(thisRef:Fragment,property:KProperty<*>,value:T){_value=value}}/**
* Creates an [AutoClearedValue] associated with this fragment.
*/fun<T:Any>Fragment.autoCleared()=AutoClearedValue<T>(this)
구조를 보면 AutoclearedValue는 viewLifecycleOwnerLiveData를 구독하고 있습니다. 따라서 onDestroy의 타이밍에 바인딩을 자동으로 해방시켜 줍니다. 그러면 _binding을 사용하던 위의 코드는 AutoclearedValue를 적용해서 다음과 같이 다시 쓸 수 있습니다.