RxSwift.Observable 从闭包到函数重构 `compactMap` 后的内存泄漏

Memory leak after refactoring `compactMap` for RxSwift.Observable from closure to function

我发现我的代码中可能存在泄漏,因为单元测试测试是否在 deinit:

处调用依赖项
func testDeinit_ShouldStopMinutesTicker() throws {
    let minutesTicker = MockMinutesTicker(elapsedTicksAfterStart: [(), (), ()])
    var viewModel: AppointmentViewModel? = createAppointmentViewModel(minutesTicker: minutesTicker)
    viewModel = nil
    
    XCTAssertTrue(minutesTicker.isStopCalled)
}

这个测试通常是绿色的。但是当我重构这个时:

func selectAppointment(index: Int) {
    selectedCellParamRelay.accept(index)
}

private func setupCellParamSelection() {
    selectedCellParamRelay
        .withLatestFrom(sortedCellParams) { ([=12=], ) }
        .compactMap { [weak self] index, cellParams in
            guard let `self` = self,
                  let selectedParam = cellParams[safe: index],
                  self.isUpcomingAppointment(selectedParam) else { return nil }
            
            return selectedParam
            
        }
        .bind(to: upcomingCellParamRelay)
        .disposed(by: disposeBag)
}

进入这个:

func selectAppointment(index: Int) {
    selectedCellParamRelay.accept(index)
}

private func setupCellParamSelection() {
    selectedCellParamRelay
        .withLatestFrom(sortedCellParams) { ([=13=], ) }
        .compactMap(selectAppointment(index:from:))
        .bind(to: upcomingCellParamRelay)
        .disposed(by: disposeBag)
}

private func selectAppointment(
    index: Int,
    from cellParams: [AppointmentCellParam]
) throws -> AppointmentCellParam? {
    guard let selectedParam = cellParams[safe: index],
          isUpcomingAppointment(selectedParam) else { return nil }

    return selectedParam
}

private func isUpcomingAppointment(_ appointment: AppointmentCellParam) -> Bool {
    return appointment.status != .missed && appointment.status != .finished
}

它变成红色,deinit根本没有被调用。

正在从 init 调用 setupCellParamSelection 函数来设置事件处理程序以按索引选择任何约会单元格。 sortedCellParams 是由依赖项发出的中继,依赖项又会从后端获取值。

你能帮我看看第二个代码哪里出了问题吗?

谢谢。

是的,因为 .compactMap(selectAppointment(index:from:)) 需要保持 self 才能调用 selectAppointment,即使函数不需要 self。

这里的解决方案是将 isUpcomingAppointment(_:)selectAppointment(index:from:) 移到 class 之外,或者作为 class.

中的静态函数