据我所知,WeakReference将允许垃圾收集器清除其引用,如果不再需要它作为强引用(例如正在销毁的Activity或正在清理的ViewModel)。但我试图理解这样一种情况:当函数的拥有实例没有被垃圾收集时,我的函数WeakReference在随机点返回一个空引用...
考虑以下ViewModel:
class SampleVM(dao: MyRoomDao) : ViewModel() {
private val mLiveData: LiveData<List<Object>> = dao.loadAll()
private val mMediatorLiveData: MediatorLiveData<List<Object>> = MediatorLiveData()
init {
mMediatorLiveData.addSource(mLiveData, { dbResult ->
MyAsyncTask(
mMediatorLiveData::setValue
).execute(dbResult ?: ArrayList())
})
...
}
我将原始LiveData的结果传递给AsyncTask,并将function type reference传递给setValue,以便AsyncTask可以在onPostExecute()中调用介体的setValue()。
考虑以下AsyncTask:
class MyAsyncTask(onFinishCallback: (List<Object>) -> Unit) : AsyncTask<...,...,...>() {
private val mOnFinishCallback = WeakReference<(List<Object>) -> Unit>(onFinishCallback)
...(overrides)...
override fun onPostExecute(result: List<Object>?) {
result?.let {
mOnFinishCallback.get()?.invoke(it)
}
我认为只要onCleared()没有在ViewModel上调用,并且它没有被垃圾收集,WeakReference将始终包含非空引用。但碰巧有两种情况我已经看到mOnFinishCallback.get()返回null。
知道为什么会这样吗?如果我的ViewModel和MediatorLiveData仍然处于活动状态并且没有被垃圾收集,那么MediatorLiveData的setValue()函数引用是否应该在整个时间内都有效?
答案 0 :(得分:0)
当您的方法MediatorLiveData::addSource
返回时,没有强烈的引用您的功能界面(您想要调用mMediatorLiveData::setValue
),这意味着它适用于GC。
从不存在对函数本身的实例变量引用,它只是一个方法参数。
您应该持有对功能界面本身的引用,只要您需要它,因此它可以调用setValue
。