Szukaj…


Wprowadzenie

Kotlin może delegować implementację właściwości do obiektu obsługi. Uwzględniono niektóre standardowe procedury obsługi, takie jak leniwa inicjalizacja lub obserwowalne właściwości. Można również tworzyć niestandardowe programy obsługi.

Leniwa inicjalizacja

val foo : Int by lazy { 1 + 1 }
println(foo)

Przykład drukuje 2 .

Obserwowalne właściwości

var foo : Int by Delegates.observable("1") { property, oldValue, newValue ->
    println("${property.name} was changed from $oldValue to $newValue")
}
foo = 2

Przykładowe wydruki foo was changed from 1 to 2

Właściwości wspierane przez mapę

val map = mapOf("foo" to 1)
val foo : String by map
println(foo)

Przykład drukuje 1

Niestandardowe delegowanie

class MyDelegate {
    operator fun getValue(owner: Any?, property: KProperty<*>): String {
        return "Delegated value"
    }
}

val foo : String by MyDelegate()
println(foo)

W tym przykładzie wydrukowano Delegated value

Delegat Może być stosowany jako warstwa zmniejszająca płytę grzewczą

Rozważmy system WeakReference<T> Kotlin i WeakReference<T> .

Powiedzmy, że musimy zapisać jakiś odnośnik i chcieliśmy uniknąć wycieków pamięci, oto gdzie pojawia się WeakReference .

weźmy na przykład to:

class MyMemoryExpensiveClass {
    companion object {
        var reference: WeakReference<MyMemoryExpensiveClass>? = null

        fun doWithReference(block: (MyMemoryExpensiveClass) -> Unit) {
            reference?.let {
                it.get()?.let(block)
            }
        }
    }

    init {
        reference = WeakReference(this)
    }
}

Teraz jest to tylko jeden WeakReference. Aby zmniejszyć tę liczbę, możemy użyć niestandardowego delegata właściwości, który pomoże nam w następujący sposób:

class WeakReferenceDelegate<T>(initialValue: T? = null) : ReadWriteProperty<Any, T?> {
    var reference = WeakReference(initialValue)
        private set
    
    override fun getValue(thisRef: Any, property: KProperty<*>): T? = reference.get()
    
    override fun setValue(thisRef: Any, property: KProperty<*>, value: T?) {
        reference = WeakReference(value)
    }
}

Teraz możemy używać zmiennych opakowanych w WeakReference podobnie jak normalne zmienne dopuszczające wartości zerowe!

class MyMemoryExpensiveClass {
    companion object {
        var reference: MyMemoryExpensiveClass? by WeakReferenceDelegate<MyMemoryExpensiveClass>()

        fun doWithReference(block: (MyMemoryExpensiveClass) -> Unit) {
            reference?.let(block)
        }
    }

    init {
        reference = this
    }
}


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow