是否应该将 coroutineScope 作为函数参数传递?

2023-12-21

我正在尝试协程,并且不确定是否将 coroutineScope 传递给普通的 Kotlin UseCase。这种方法会造成内存泄漏吗?

假设我们正在虚拟机中初始化我们的用例并尝试通过视图模型范围:

class UploadUseCase(private val imagesPreparingForUploadUseCase: ImagesPreparingForUploadUseCase){

fun execute(coroutineScope: CoroutineScope, bitmap: Bitmap) {
        coroutineScope.launch {
            val resizedBitmap = withContext(Dispatchers.IO) {
                imagesPreparingForUploadUseCase.getResizedBitmap(bitmap, MAX_SIZE)
            }
        }
    }

}

它是安全代码吗?如果我在 VM 中声明这个确切的代码,没有什么区别?如果不是,这意味着我可以将 coroutineScope 作为构造函数参数传递......现在我最初认为我应该通过以下方式创建我的执行方法:

fun CoroutineScope.execute(bitmap: Bitmap) {
        launch {
            val resizedBitmap = withContext(Dispatchers.IO) {
                imagesPreparingForUploadUseCase.getResizedBitmap(bitmap, MAX_SIZE)
            }
        }
    }

}

据我了解,我们使用扩展函数来使用方法父协程作用域。这意味着,我不需要传递 coroutineScope 作为参数,只需更改方法即可使用扩展函数。

然而,令我惊讶的是,虚拟机看不到这个方法可用!为什么VM无法调用该方法?

这在 VM 中标记为红色:

 private fun uploadPhoto(bitmap: Bitmap, isImageUploaded: Boolean) {
        prepareDataForUploadingUseCase.execute(bitmap)
    }

VM 中未将其标记为红色:

 private fun uploadPhoto(bitmap: Bitmap, isImageUploaded: Boolean) {
        prepareDataForUploadingUseCase.execute(viewModelScope, bitmap)
    }

如果我的理解是错误的,为什么我要用 CoroutineScope 作为扩展函数而不是将 coroutineScope 作为函数参数传递?


将其作为参数传递与将其用作扩展函数接收器在最终结果中实际上是相同的。扩展函数接收器基本上是传递给函数的另一个参数,只是为了方便而重新排列了语法。所以你不能使用扩展函数作为“作弊”来避免传递接收者。

但无论哪种方式,我都认为这是一种笨拙的设计,必须提供一个范围,然后将协程设置隐藏在函数内。这导致协程作用域操作分散到函数屏障的两侧。调用此函数的函数必须意识到某些协程将在其传递的范围内被调用,但它不知道是否需要担心如何处理取消以及允许对该范围执行什么操作它过去了。

在我看来,这样做会更干净:

suspend fun execute(bitmap: Bitmap) = withContext(Dispatchers.IO) {
        imagesPreparingForUploadUseCase.getResizedBitmap(bitmap, MAX_SIZE)
    }

因此调用函数可以启动协程并在一个地方处理整个协程。或者不传递协程作用域,但有execute函数内部生成自己的作用域(即依赖于lifecycleScope or viewModelScope如果适用),并处理其自己的取消行为。下面是创建生命周期作用域的子作用域并将其添加到您在某些情况下可能想要取消的某些作业集合的示例。

fun execute(bitmap: Bitmap) {
    lifecycleScope.launch {
        bitmapScopes += coroutineScope(Dispatchers.IO) {
            imagesPreparingForUploadUseCase.getResizedBitmap(bitmap, MAX_SIZE)
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

是否应该将 coroutineScope 作为函数参数传递? 的相关文章

随机推荐