在Kotlin中,實現觀察者模式時,處理訂閱取消的關鍵是使用WeakReference
來引用觀察者對象,以便在內存不足時可以被垃圾回收器回收。同時,在觀察者注冊時,將訂閱者存儲在一個可取消訂閱的集合中。當需要取消訂閱時,從該集合中移除對應的訂閱者。以下是一個簡單的示例:
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)
// 再次通知觀察者,此時不會有任何輸出
observable.notifyObservers("Hello again, but no one is listening.")
}
在這個示例中,我們創建了一個Observable
類,它允許觀察者通過subscribe
方法注冊,并通過unsubscribe
方法取消訂閱。我們使用CopyOnWriteArrayList
來存儲觀察者的弱引用,這樣在迭代過程中可以安全地添加或刪除元素。當我們需要通知觀察者時,我們遍歷這個列表并調用每個觀察者的update
方法。由于我們使用了弱引用,所以當觀察者不再被其他地方引用時,垃圾回收器可以回收它,從而避免內存泄漏。