委託可以用作減少樣板的圖層

考慮 Kotlin 的 Null Type 系統和 WeakReference<T>

所以,假設我們必須儲存某種引用,我們希望避免記憶體洩漏,這裡是 WeakReference 的用武之地。

以此為例:

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

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

    init {
        reference = WeakReference(this)
    }
}

現在這只是一個 WeakReference。要減少此樣板,我們可以使用自定義屬性委託來幫助我們:

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)
    }
}

所以現在我們可以像普通的可空變數一樣使用 WeakReference 包裝的變數!

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

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

    init {
        reference = this
    }
}