为了账号安全,请及时绑定邮箱和手机立即绑定

CompositeDisposable 会导致内存泄漏,直到 clear 或 dispose 调用?

CompositeDisposable 会导致内存泄漏,直到 clear 或 dispose 调用?

一只萌萌小番薯 2022-07-06 18:49:31
Disposable添加到遗嘱中的每个都被CompositeDisposable强烈引用,CompositeDisposable直到CompositeDisposable清除或处置。这将防止收集订阅者(一次性)强引用的对象。我应该在添加Disposable到WeakReference之前将所有内容包装起来CompositeDisposable吗?或者只是忽略并让CompositeDisposable将来清除。
查看完整描述

1 回答

?
catspeake

TA贡献1111条经验 获得超0个赞

订阅时上游对下游的强引用。当上游没有完成任务时,最终的Disposable Observer仍然可以被这个容器处理掉。


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

}


查看完整回答
反对 回复 2022-07-06
  • 1 回答
  • 0 关注
  • 320 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号