코틀린은 delegated properties에 대한 내장 지원을 제공합니다. by 메커니즘은 속성의 getter/setter를 특정 객체인 위임자에게 위임할 수 있게 해줍니다. 가장 잘 알려진 위임자에는 lazy, observable, vetoable 및 사용자 정의가 있습니다.
장점:
사용자 정의 위임자 예제:
class UpperCaseDelegate { private var value: String = "" operator fun getValue(thisRef: Any?, property: KProperty<*>): String = value operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: String) { value = newValue.uppercase() } } class Person { var name: String by UpperCaseDelegate() }
제한 사항:
Context(예: Android Context)에 접근해야 하는 위임자를 companion 객체나 최상위 객체 속성에서 사용할 수 있습니까?
종종 "가능하다, 왜 안되겠는가?"라는 잘못된 대답을 합니다.
정답: 아니요, companion 객체와 최상위 객체는 클래스 인스턴스나 애플리케이션 초기화 전에 초기화되므로 초기화되지 않은 컨텍스트에 접근할 수 있는 오류가 발생할 수 있습니다. 인스턴스에 접근해야 하는 위임자는 클래스 속성에서만 사용해야 합니다.
사례
Android-ViewModel에서 지연 초기화 위임: 프로그래머는 heavy-lazy 위임자를 companion 객체로 옮겼습니다. 특정 상황에서(SDK 업데이트 후) 애플리케이션이 초기화 중에 충돌하기 시작했습니다 - 컨텍스트가 아직 사용 가능하지 않았지만 위임자는 이미 자신의 "init"을 수행했습니다.
사례
위임자를 통한 잘못된 직렬화: 데이터를 저장하기 위해 사용자 정의 위임자를 사용했으나, 이 위임자는 컨텍스트에 대한 직렬화할 수 없는 참조를 포함하고 있었습니다. 직렬화 시도를 할 때 오류가 발생하고 데이터가 손실되었습니다.
사례
잘못된 콜백을 가진 Observable 위임자: 개발자는 상태 모니터링을 위해 Delegates.observable을 사용했으며, 람다 내에서 새로운 값을 할당하면서 루프와 StackOverflowError가 런타임에 발생했습니다.