Skip to content

Commit 0a96fa2

Browse files
authored
Merge pull request #170 from RxSwiftCommunity/release/2-12-1
Release/2 12 1
2 parents b0883bc + c1d2902 commit 0a96fa2

File tree

5 files changed

+57
-6
lines changed

5 files changed

+57
-6
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
** Version 2.12.1 **:
2+
3+
- fix a possible memory leak when the Coordinator's lifecycle was unexpectedly longer than the flow ones (thanks to @asiliuk)
4+
15
** Version 2.12.0 **:
26

37
- bump to RxSwift 6.0.0

RxFlow.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = "RxFlow"
3-
s.version = "2.12.0"
3+
s.version = "2.12.1"
44
s.swift_version = '5.3'
55
s.summary = "RxFlow is a navigation framework for iOS applications, based on a Reactive Coordinator pattern."
66

RxFlow.xcodeproj/project.pbxproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,7 @@
604604
"@executable_path/Frameworks",
605605
"@loader_path/Frameworks",
606606
);
607-
MARKETING_VERSION = 2.11.0;
607+
MARKETING_VERSION = 2.12.1;
608608
PRODUCT_BUNDLE_IDENTIFIER = io.warpfactor.RxFlow;
609609
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
610610
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -639,7 +639,7 @@
639639
"@executable_path/Frameworks",
640640
"@loader_path/Frameworks",
641641
);
642-
MARKETING_VERSION = 2.11.0;
642+
MARKETING_VERSION = 2.12.1;
643643
PRODUCT_BUNDLE_IDENTIFIER = io.warpfactor.RxFlow;
644644
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
645645
PROVISIONING_PROFILE_SPECIFIER = "";

RxFlow/FlowCoordinator.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,11 @@ public final class FlowCoordinator: NSObject {
4646
// listen for the internal steps relay that aggregates the flow's Stepper's steps and
4747
// the FlowContributors's Stepper's steps
4848
self.stepsRelay
49-
.take(until: allowStepWhenDismissed ? .empty() : flow.rxDismissed.asObservable())
5049
.do(onDispose: { [weak self] in
5150
self?.childFlowCoordinators.removeAll()
5251
self?.parentFlowCoordinator?.childFlowCoordinators.removeValue(forKey: self?.identifier ?? "")
5352
})
54-
.asSignal(onErrorJustReturn: NoneStep())
55-
.flatMapLatest { flow.adapt(step: $0).asSignal(onErrorJustReturn: NoneStep()) }
53+
.flatMapLatest { flow.adapt(step: $0) }
5654
.do(onNext: { [weak self] in self?.willNavigateRelay.accept((flow, $0)) })
5755
.map { return (flowContributors: flow.navigate(to: $0), step: $0) }
5856
.do(onNext: { [weak self] in self?.didNavigateRelay.accept((flow, $0.step)) })
@@ -98,6 +96,8 @@ public final class FlowCoordinator: NSObject {
9896
.flatMap { [weak self] in
9997
self?.steps(from: $0, within: flow, allowStepWhenDismissed: allowStepWhenDismissed) ?? Signal.empty()
10098
}
99+
.take(until: allowStepWhenDismissed ? .empty() : flow.rxDismissed.asObservable())
100+
.asSignal(onErrorJustReturn: NoneStep())
101101
.emit(to: self.stepsRelay)
102102
.disposed(by: self.disposeBag)
103103

RxFlowTests/FlowCoordinatorTests.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,28 @@ final class TestDismissedFlow: Flow {
207207
}
208208
}
209209

210+
final class TestLeakingFlow: Flow {
211+
var root: Presentable = UIViewController()
212+
213+
var rxDismissed: Single<Void> { rxDismissedRelay.take(1).asSingle() }
214+
let rxDismissedRelay = PublishRelay<Void>()
215+
216+
func navigate(to step: Step) -> FlowContributors {
217+
guard let step = step as? TestSteps else { return .none }
218+
219+
switch step {
220+
case .one:
221+
let flowContributor = FlowContributor.contribute(
222+
withNextPresentable: UIViewController(),
223+
withNextStepper: DefaultStepper()
224+
)
225+
return .one(flowContributor: flowContributor)
226+
default:
227+
return .none
228+
}
229+
}
230+
}
231+
210232
final class FlowCoordinatorTests: XCTestCase {
211233

212234
func testCoordinateWithOneStepper() {
@@ -320,6 +342,31 @@ final class FlowCoordinatorTests: XCTestCase {
320342
let recordedSteps = try? dismissedFlow.recordedSteps.take(3).toBlocking().toArray()
321343
XCTAssertEqual(recordedSteps, [.one, .two, .three])
322344
}
345+
346+
func testFlowIsNotLeakingWhenHasOneStep() throws {
347+
weak var leakingFlowReference: TestLeakingFlow?
348+
let exp = expectation(description: "Flow when ready")
349+
let flowCoordinator = FlowCoordinator()
350+
351+
withExtendedLifetime(TestLeakingFlow()) { leakingFlow in
352+
leakingFlowReference = leakingFlow
353+
354+
flowCoordinator.coordinate(flow: leakingFlow,
355+
with: OneStepper(withSingleStep: TestSteps.one))
356+
357+
Flows.use(leakingFlow, when: .created) { (_) in
358+
exp.fulfill()
359+
}
360+
}
361+
362+
waitForExpectations(timeout: 1)
363+
364+
XCTAssertNotNil(leakingFlowReference)
365+
366+
try XCTUnwrap(leakingFlowReference).rxDismissedRelay.accept(Void())
367+
368+
XCTAssertNil(leakingFlowReference)
369+
}
323370
}
324371

325372
#endif

0 commit comments

Comments
 (0)