ursus
03/13/2023, 4:47 PMclass FooViewModel(
private val someUseCase: UseCase
) {
fun fooClicked() {
applicationScope.launch {
someUseCase.doWhatever() <-----------
}
}
}
Does the launch
lambda capture this
? or is it smart enough to just capture the fieldCLOVIS
03/13/2023, 4:49 PMursus
03/13/2023, 4:50 PMthis.someUseCase
Loney Chou
03/13/2023, 4:51 PMthis
.ursus
03/13/2023, 4:52 PMCLOVIS
03/13/2023, 4:52 PMCLOVIS
03/13/2023, 4:52 PMursus
03/13/2023, 4:53 PMLoney Chou
03/13/2023, 4:53 PMCLOVIS
03/13/2023, 4:54 PMthis
then.CLOVIS
03/13/2023, 4:54 PMCLOVIS
03/13/2023, 4:55 PMLoney Chou
03/13/2023, 4:56 PMursus
03/13/2023, 4:57 PMfun fooClicked() {
applicationScope.launch { [this] in
this.someUseCase.doWhatever()
}
}
instead of
fun fooClicked() {
applicationScope.launch { [someUseCase] in
someUseCase.doWhatever()
}
}
?ursus
03/13/2023, 5:03 PM// access flags 0x11
public final onActivateClick()V
L0
LINENUMBER 77 L0
ALOAD 0
GETFIELD cz/yav/scratchcards/presentation/activation/ActivationScreenViewModel.coroutineScope : Lkotlinx/coroutines/CoroutineScope;
ACONST_NULL
ACONST_NULL
NEW cz/yav/scratchcards/presentation/activation/ActivationScreenViewModel$onActivateClick$1
DUP
ALOAD 0
ACONST_NULL
INVOKESPECIAL cz/yav/scratchcards/presentation/activation/ActivationScreenViewModel$onActivateClick$1.<init> (Lcz/yav/scratchcards/presentation/activation/ActivationScreenViewModel;Lkotlin/coroutines/Continuation;)V
CHECKCAST kotlin/jvm/functions/Function2
ICONST_3
ACONST_NULL
INVOKESTATIC kotlinx/coroutines/BuildersKt.launch$default (Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/CoroutineContext;Lkotlinx/coroutines/CoroutineStart;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lkotlinx/coroutines/Job;
POP
L1
LINENUMBER 80 L1
RETURN
L2
LOCALVARIABLE this Lcz/yav/scratchcards/presentation/activation/ActivationScreenViewModel; L0 L2 0
MAXSTACK = 7
MAXLOCALS = 1
ursus
03/13/2023, 5:03 PMLoney Chou
03/13/2023, 5:06 PMXxxViewModel
, so yes it captures this
.ursus
03/13/2023, 5:07 PMursus
03/13/2023, 5:07 PMALOAD 0
means load this, right?ursus
03/13/2023, 5:08 PM// access flags 0x11
public final invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;
@Lorg/jetbrains/annotations/Nullable;() // invisible
// annotable parameter count: 1 (visible)
// annotable parameter count: 1 (invisible)
@Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
INVOKESTATIC kotlin/coroutines/intrinsics/IntrinsicsKt.getCOROUTINE_SUSPENDED ()Ljava/lang/Object;
L0
LINENUMBER 80 L0
ASTORE 2
ALOAD 0
GETFIELD cz/yav/scratchcards/presentation/activation/ActivationScreenViewModel$fooClick$1.label : I
TABLESWITCH
0: L1
1: L2
default: L3
L1
ALOAD 1
INVOKESTATIC kotlin/ResultKt.throwOnFailure (Ljava/lang/Object;)V
L4
LINENUMBER 81 L4
ALOAD 0
GETFIELD cz/yav/scratchcards/presentation/activation/ActivationScreenViewModel$fooClick$1.this$0 : Lcz/yav/scratchcards/presentation/activation/ActivationScreenViewModel;
INVOKESTATIC cz/yav/scratchcards/presentation/activation/ActivationScreenViewModel.access$getFooManager$p (Lcz/yav/scratchcards/presentation/activation/ActivationScreenViewModel;)Lcz/yav/scratchcards/presentation/activation/FooManager;
ALOAD 0
ALOAD 0
ICONST_1
PUTFIELD cz/yav/scratchcards/presentation/activation/ActivationScreenViewModel$fooClick$1.label : I
INVOKEVIRTUAL cz/yav/scratchcards/presentation/activation/FooManager.doFoo (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
L5
DUP
ALOAD 2
IF_ACMPNE L6
L7
LINENUMBER 80 L7
ALOAD 2
ARETURN
L2
ALOAD 1
INVOKESTATIC kotlin/ResultKt.throwOnFailure (Ljava/lang/Object;)V
ALOAD 1
L6
LINENUMBER 82 L6
POP
L8
GETSTATIC kotlin/Unit.INSTANCE : Lkotlin/Unit;
ARETURN
L3
LINENUMBER 80 L3
NEW java/lang/IllegalStateException
DUP
LDC "call to 'resume' before 'invoke' with coroutine"
INVOKESPECIAL java/lang/IllegalStateException.<init> (Ljava/lang/String;)V
ATHROW
LOCALVARIABLE this Lcz/yav/scratchcards/presentation/activation/ActivationScreenViewModel$fooClick$1; L4 L3 0
LOCALVARIABLE $result Ljava/lang/Object; L4 L3 1
MAXSTACK = 4
MAXLOCALS = 3
ursus
03/13/2023, 5:09 PMursus
03/13/2023, 5:10 PMLoney Chou
03/13/2023, 5:11 PMursus
03/13/2023, 5:12 PMursus
03/13/2023, 5:13 PMclass FooSender(private val useCase) {
private val scope = CoroutineScope()
fun doFoo() {
scope.launch {
useCase.doWhatever()
}
}
}
class FooViewModel(
private val fooSender: FooSender
) {
fun fooClicked() {
fooSender.doFoo()
}
}
like so
now, nothing leaks, when view model dies