每次调用newSuspendFunction
都会创建InterfaceWithCallback
的一个新实例,因为lambda捕获的延续cont
每次调用suspendCoroutine
时都是不同的.
话虽如此,但这并不意味着这种开销会很大.对于垃圾回收器来说,生存期较短的对象可能不是大问题.您需要衡量这是否真的会对性能产生可衡量的影响.
此外,您的循环中不需要yield()
,因为newSuspendFunction
已经是一个实际挂起的挂起函数.
最后但同样重要的是,为什么要打这.let
个电话?我发现在可能的时候避免嵌套块更具可读性.您可以使用变量而不是let
:)
编辑:现在,你的用例似乎需要一个Flow
而不是一个挂起函数,因为你的回调被反复调用.您可以使用callbackFlow
来包装基于回调的API:
// replace Int with whatever type you're dealing with
fun someUsefulName(): Flow<Int> = callbackFlow {
val callback = InterfaceWithCallback { value ->
trySendBlocking(value)
}
registerInterfaceWithCallback(callback)
// suspends until the flow collector is cancelled, and unregisters
awaitClose {
// there should be some kind of 'unregister' counterpart
unregisterInterfaceWithCallback(callback)
}
}
作为参考,这里是你的newSuspendFunction
的反编译字节码,在这里你可以看到new MainJvmKt$newSuspendFunction$2$1(cont)
:
@Nullable
public static final Object newSuspendFunction(@NotNull Continuation $completion) {
SafeContinuation var2 = new SafeContinuation(IntrinsicsKt.intercepted($completion));
Continuation cont = (Continuation)var2;
int var4 = false;
MainJvmKt$newSuspendFunction$2$1 var5 = new MainJvmKt$newSuspendFunction$2$1(cont);
InterfaceWithCallback myInterfaceWithCallback = (InterfaceWithCallback)var5;
int var7 = false;
registerInterfaceWithCallback(myInterfaceWithCallback);
Object var10000 = var2.getOrThrow();
if (var10000 == IntrinsicsKt.getCOROUTINE_SUSPENDED()) {
DebugProbesKt.probeCoroutineSuspended($completion);
}
return var10000 == IntrinsicsKt.getCOROUTINE_SUSPENDED() ? var10000 : Unit.INSTANCE;
}
@Metadata(
mv = {1, 9, 0},
k = 3,
d1 = {"\u0000\u000e\n\u0000\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\b\n\u0000\u0010\u0000\u001a\u00020\u00012\u0006\u0010\u0002\u001a\u00020\u0003H\n¢\u0006\u0002\b\u0004"},
d2 = {"<anonymous>", "", "value", "", "callback"}
)
final class MainJvmKt$newSuspendFunction$2$1 implements InterfaceWithCallback {
// $FF: synthetic field
final Continuation $cont;
public final void callback(int value) {
Continuation var2 = this.$cont;
Integer var3 = value;
Result.Companion var10001 = Result.Companion;
var2.resumeWith(Result.constructor-impl(var3));
}
MainJvmKt$newSuspendFunction$2$1(Continuation var1) {
this.$cont = var1;
}
}
这里假设InterfaceWithCallback
被声明为:
fun interface InterfaceWithCallback {
fun callback(value: Int)
}