简体   繁体   English

RxSwift`.addDisposableTo(disposeBag)`导致内存泄漏

[英]RxSwift `.addDisposableTo(disposeBag)` causes memory leak

I am using heavily in my companies project RxSwift. 我在我的公司项目RxSwift中大量使用。 And when running performance tests in Instrument really worrying problem appeared. 当在Instrument中运行性能测试时,确实出现了令人担忧的问题。

Each time .addDisposableTo(disposeBag) gets called, Instruments show up memory leak around 10 bytes. 每次.addDisposableTo(disposeBag)时,仪器都会显示大约10个字节的内存泄漏。 There's no specific pattern of why it would happen, like not using [weak self] in right places, it just happens for no apparent reason. 没有特定的发生原因的模式,例如没有在正确的地方使用[weak self] ,只是没有明显的原因而发生。

Some sample code: 一些示例代码:

class ContactsViewModel: NSObject {
    fileprivate let disposeBag = DisposeBag()
    fileprivate let provider = AuthorizedNetworking().provider

    var contacts: Variable<[User]> = Variable([])
    var suggestedContacts: Variable<[User]> = Variable([])

    func fetchContact(suggestions: Bool = false) {
        ActivityIndicator.showLoadingHUD(message: "Fetching contacts...")
        let observable = provider.request(suggestions ?
            .suggest :
            .searchContacts(query: nil, global: false)).filterSuccessfulStatusCodes()
        let mapped = observable.checkForErrors().mapObject(DataListResponse<User>.self)
        mapped.subscribe { [weak self] event in
            switch event {
            case let .next(response):
                ActivityIndicator.hideLoadingHUD()
                if response.success, let contacts = response.data {
                    if suggestions {
                        self?.suggestedContacts.value = contacts
                    } else {
                        self?.contacts.value = contacts.filter { $0.contactType == "Friend" }
                    }
                } else {
                    Log(.Network, .Error, "Unable to retrieve current user")
                }
            case let .error(error):
                ActivityIndicator.hideLoadingHUD()
                Log(.Network, .Error, error.localizedDescription)
            default:
                break
            }
            }.addDisposableTo(disposeBag) <- Instruments show leak [6 bytes] at this line

    }
}

I've done some research and I have one version that Instrument might not understand RxSwift and make it look like there's leak but in reality, there isn't. 我已经做过一些研究,并且我有一个版本,Instrument可能不理解RxSwift并使它看起来好像有泄漏,但实际上没有泄漏。 But most likely my implementation has problems that I don't know of since I have little experience in RxSwift. 但是由于我对RxSwift的经验很少,所以我的实现很可能会遇到未知的问题。 Any help appreciated. 任何帮助表示赞赏。

I would get a second opinion using RxSwift resource debugging features. 我将使用RxSwift资源调试功能获得第二意见。 You can debug memory leaks using the RxSwift.Resources.total variable to be sure that the problem is RxSwift and not a false positive of Instruments. 您可以使用RxSwift.Resources.total变量调试内存泄漏,以确保问题是RxSwift而不是对Instruments的误判。

Enable debug mode as explained in RxSwift issue #378 , add this code to your app delegate: 如RxSwift问题#378中所述 ,启用调试模式,将此代码添加到您的应用程序委托中:

/* add somewhere in
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil)
*/
_ = Observable<Int>.interval(1, scheduler: MainScheduler.instance)
    .subscribe(onNext: { _ in
        print("Resource count \(RxSwift.Resources.total)")
    })

and use several times your observables to see if the total number of resources is always the same at the end of the process. 并使用您的可观察值的几次,以查看该过程结束时资源总数是否始终相同。

Finally, take into account that if the object that contains the observable or the dispose bag is leaked, the problem is the container object, not observables. 最后,考虑到如果包含可观察物或处理袋的对象泄漏,则问题出在容器对象而不是可观察物。 I was leaking a view and a controller due to a problem with Facebook SDK, and I found the issue when debugging the observables used inside the controller :) . 由于Facebook SDK出现问题,我泄漏了视图和控制器,并且在调试控制器内部使用的可观察对象时发现了问题:)。

I hope it helps, Xavi 希望对您有帮助,Xavi

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM