2017-07-28 42 views
1

我在我的公司项目RxSwift中大量使用。在Instrument中执行性能测试时,真正令人担忧的问题出现了。RxSwift`.addDisposableTo(disposeBag)`导致内存泄漏

每次.addDisposableTo(disposeBag)被调用时,Instruments都会显示10个字节左右的内存泄漏。没有具体的模式,为什么会发生,就像没有在正确的地方使用[weak self],它只是没有明显的原因发生。

一些示例代码:

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 

    } 
} 

我做了一些研究,我有一个版本的仪器可能不明白RxSwift,使它看起来像有泄漏,但在现实中,没有。 但是很可能我的实现有一些我不知道的问题,因为我在RxSwift方面的经验不多。 任何帮助表示赞赏。

回答

1

我会使用RxSwift资源调试功能得到第二个意见。您可以使用RxSwift.Resources.total变量调试内存泄漏,以确定问题是RxSwift,而不是仪器的误报。

启用调试模式,如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)") 
    }) 

,并多次使用你的观测,看看资源的总数总是在结束同的过程。

最后,考虑到如果包含observable或dispose包的对象泄漏,问题是容器对象,而不是可观察对象。由于Facebook SDK的问题,我正在泄漏视图和控制器,并且在调试控制器内部使用的observables时发现问题:)。

我希望它有帮助, Xavi