添加到Disposable
的每个CompositeDisposable
都会被CompositeDisposable
强烈引用,直到CompositeDisposable
被清除或处置。这样可以防止收集由订户(一次性)强烈引用的对象。
在添加到Disposable
之前,我应该将所有WeakReference
包装到CompositeDisposable
吗?或者只是忽略并让CompositeDisposable
将来被清除。
答案 0 :(得分:0)
订阅时上游强烈引用下游。 当上游未完成任务时,最终 Disposable 观察者仍然可以被此容器处置。
import io.reactivex.disposables.Disposable
import io.reactivex.exceptions.CompositeException
import io.reactivex.internal.disposables.DisposableContainer
import java.util.*
import kotlin.collections.ArrayList
class WeakDisposableContainer : DisposableContainer, Disposable {
private val container = WeakHashMap<Disposable, Any>()
@Volatile
private var disposed = false
override fun add(d: Disposable): Boolean {
if (!disposed) {
synchronized(this) {
if (!disposed) {
container[d] = Unit
return true
}
}
}
d.dispose()
return false
}
override fun remove(d: Disposable): Boolean {
if (delete(d)) {
d.dispose()
return true
}
return false
}
override fun delete(d: Disposable): Boolean {
if (disposed) return false
synchronized(this) {
if (disposed) return false
return container.remove(d) != null
}
}
override fun isDisposed(): Boolean = disposed
override fun dispose() {
clear()
disposed = true
}
fun clear() {
if (disposed) return
val d: Iterable<Disposable>
synchronized(this) {
if (disposed) return
d = ArrayList(container.keys)
container.clear()
}
val err = d.mapNotNull { catchThrowable { it.dispose() } }
if (err.isNotEmpty()) throw CompositeException(err)
}
}
inline fun catchThrowable(block: () -> Unit): Throwable? = try {
block()
null
} catch (e: Throwable) {
e
}