이동 가능한 그룹
이동 가능한 그룹이란 정체성을 잃지 않고 재정렬이 가능한 그룹을 의미한다.
이 그룹의 특징은 key함수의 내부에서 Composable 함수를 호출하는 경우에만 활용된다 (리스트와 같이)
아래 코드를 한번 살펴보자.
@Composable
fun TalksScreen(talks: List<Talk>) {
Column {
for (talk in talks){
key(talk.id) { <-- Unique Key
Talk(talk)
}
}
}
}
고유한 키값을 기준으로 key 함수로 Talk 함수를 감싸서 사용하면 Talk Composable 함수마다의 고유한 정체성이 보장되면서도 이동 가능한 그룹이 생성된다.
이 작업은 호출된 각 Composable 함수마다 정체성을 해치지 않으면서도 호출 순서를 변경할 수 있다.
key함수가 사용될 때 내부 Composable이 어떻게 동작하는지 알아보자.
//Before
@Composable
fun Test(value: Int) {
key(value) {
Wrapper {
Leaf("Value ${'$'}value")
}
}
}
//After
@Composable
fun Test(value: Int, %composer: Composer?, %changed: Int) {
%composer.startMovableGroup(<>, value)
Wrapper(composableLamda(%composer, <>, true) { %composer: Composer?, %changed:\\
Int -> Leaf("Value %value", %composer, 0)
}, %composer, 0b0110)
%composer.endMovableGroup()
}
재시작 가능한 그룹
이 그룹은 재시작 가능한 Composable 함수에만 적용된다.
재시작 가능한 그룹 또한 해당 Composable을 감싸지만, 여기서 end 함수 호출을 약간 변형하여 nullable 한 값을 반한다.
이 반환값이 null이 되는 조건은 Composable 함수가 어떤 상태도 읽지 않을 때만 해당되며, 결과적으로 recomposition이 필요 없다는 얘기가 된다.
이런 경우엔 Runtime에게 해당 Composable을 재구성할 시그널을 줄 필요가 없다. 만약 null이 아닌 값을 반환하는 경우, 컴파일러는 composition을 업데이트하기 위해 람다식을 생성하는데, 그. 람다식은 Composable을 재시작하도록 Runtime에 시그널을 보낸다.
//Compiler 동작 전
@Composable
fun A(x: Int) {
f(x)
}
//Compiler 동작 후
fun A(x: Int, $composer: Composer<*>, $changed: Int) {
$composer.startREstartGroup()
//...
f(x)
$composer.endRestartGroup()?.updateScope { next ->
A(x, next, $changed or 0b1)
}
}
A()라는 Composable 함수에 대해 동일한 새 호출을 감싸고 recomposition을 트리거하기 위한 범위를 updateScope()를 통해 갱신하는 구현부이다.
재시작 가능한 그룹은 상태를 읽는 모든 Composable을 실행하는 그룹이다.
'Android' 카테고리의 다른 글
[Android] Compose 런타임 - (2) (0) | 2024.11.26 |
---|---|
[Android] Compose 런타임 - (1) (0) | 2024.11.25 |
[Android] Compose 컴파일러 - (7) (0) | 2024.11.21 |
[Android] Compose 컴파일러 - (6) (0) | 2024.11.20 |
[Android] Compose 컴파일러 - (5) (0) | 2024.11.19 |