在Kotlin中,實(shí)現(xiàn)觀察者模式時(shí),處理訂閱取消的關(guān)鍵是使用WeakReference
來引用觀察者對(duì)象,以便在內(nèi)存不足時(shí)可以被垃圾回收器回收。同時(shí),在觀察者注冊(cè)時(shí),將訂閱者存儲(chǔ)在一個(gè)可取消訂閱的集合中。當(dāng)需要取消訂閱時(shí),從該集合中移除對(duì)應(yīng)的訂閱者。以下是一個(gè)簡(jiǎn)單的示例:
import java.lang.ref.WeakReference
import java.util.concurrent.CopyOnWriteArrayList
interface Observer {
fun update(data: String)
}
class ConcreteObserver : Observer {
override fun update(data: String) {
println("Observer received data: $data")
}
}
class Observable {
private val observers = CopyOnWriteArrayList<WeakReference<Observer>>()
fun subscribe(observer: Observer) {
observers.add(WeakReference(observer))
}
fun unsubscribe(observer: Observer) {
observers.removeAll { it.get() == observer }
}
fun notifyObservers(data: String) {
observers.forEach { it.get()?.update(data) }
}
}
fun main() {
val observable = Observable()
val observer = ConcreteObserver()
observable.subscribe(observer)
observable.notifyObservers("Hello, Observer!")
// 取消訂閱
observable.unsubscribe(observer)
// 再次通知觀察者,此時(shí)不會(huì)有任何輸出
observable.notifyObservers("Hello again, but no one is listening.")
}
在這個(gè)示例中,我們創(chuàng)建了一個(gè)Observable
類,它允許觀察者通過subscribe
方法注冊(cè),并通過unsubscribe
方法取消訂閱。我們使用CopyOnWriteArrayList
來存儲(chǔ)觀察者的弱引用,這樣在迭代過程中可以安全地添加或刪除元素。當(dāng)我們需要通知觀察者時(shí),我們遍歷這個(gè)列表并調(diào)用每個(gè)觀察者的update
方法。由于我們使用了弱引用,所以當(dāng)觀察者不再被其他地方引用時(shí),垃圾回收器可以回收它,從而避免內(nèi)存泄漏。