Android Architecture Component 중에 ViewModel 관련 예제를 보던중 특이한 코드가 있었다.
여기서 ViewModel을 생성하는 부분의 코드가 전혀 이해되지 않았다.
Delegated Properties
우리가 공통적으로 사용하는 lazy properties, observable properties, 그리고 storing properties를 쉽게 구현하기 위해서,
Kotlin에서는 Delegated Properties를 지원한다.
레퍼런스 문서에 있는 간단한 예를 살펴 보면,
p
라는 Delegated Properties를 Delegate
클래스를 사용해 선언했다.
p
를 읽을때는 Delegate
클래스의 getValue()
가 호출되고,
첫번째 파라미터는 p
를 읽은 객체이고 두번째 파라미터는 p
에 대한 KProperty
를 전달 받는다.
이를 실행하면, 아래와 같이 출력된다.
Example@33a17727, thank you for delegating ‘p’ to me!
마찬가지로 setValue()
의 경우에도 마지막 파라미터로 value가 전달되는 것을 제외하면 동일하다
NEW has been assigned to ‘p’ in Example@33a17727.
Lazy
lazy()는 lambda를 받아서 Lazy<T>
를 리턴하는 함수로, lazy property를 구현할 수 있다.
첫번째 get()
에서는 전달된 lambda가 실행되고 그 리턴값을 저장한다. 다음 호출부터는 저장된 결과가 리턴된다.
computed!
Hello
Hello
참고로, Lazy.kt를 보면 getValue
가 extension으로 정의되있고, T의 인스턴스인 value
를 리턴하게 되있다.
viewModels()
따라서, val model: MyViewModel by viewModel()
의 의미는
model의 getValue/setValue 동작을 viewModels
의 getValue/setValue의 동작에 위임하는 것이다.
아래 코드는 ActivityViewModelLazy.kt이다.
소스를 보면 model
을 접근하면 ActivityViewModelLazy
의 get
이 호출되고,
ViewModelProvider
에서 해당 MyViewModel
의 ViewModel을 가져오게 된다.
즉, Java 예제와 비교하면 lazy인 것을 제외하면 비슷한 것이다.