Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

breakRetainCycle: Break retain cycle in bind(to:input:) #228

Merged
merged 4 commits into from
Jan 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Changelog
Current master
--------------

- Nothing yet!
- Break retain cycle in `bind(to:input:)`

4.3.0
-----
Expand Down
4 changes: 3 additions & 1 deletion Sources/Action/CommonUI/Control+Action.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ public extension Reactive where Base: Control {

// For each tap event, use the inputTransform closure to provide an Input value to the action
controlEvent
.map { inputTransform(self.base) }
.withUnretained(self.base)
.map(\.0)
.map(inputTransform)
.bind(to: action.inputs)
.disposed(by: self.base.actionDisposeBag)

Expand Down
4 changes: 3 additions & 1 deletion Sources/Action/UIKitExtensions/UIBarButtonItem+Action.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ public extension Reactive where Base: UIBarButtonItem {
unbindAction()

self.tap
.map { inputTransform(self.base) }
.withUnretained(self.base)
.map(\.0)
.map(inputTransform)
.bind(to: action.inputs)
.disposed(by: self.base.actionDisposeBag)

Expand Down
4 changes: 3 additions & 1 deletion Sources/Action/UIKitExtensions/UIRefreshControl+Action.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ public extension Reactive where Base: UIRefreshControl {
unbindAction()

self.controlEvent(.valueChanged)
.map { inputTransform(self.base)}
.withUnretained(self.base)
.map(\.0)
.map(inputTransform)
.bind(to: action.inputs)
.disposed(by: self.base.actionDisposeBag)

Expand Down
40 changes: 40 additions & 0 deletions Tests/iOS-Tests/BindToTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ class BindToTests: QuickSpec {
expect(called).toEventually( beTrue() )
}

it("does not retain UIButton") {
var button: UIButton? = UIButton()
let action = Action<String, String>(workFactory: { _ in
return .empty()
})
button?.rx.bind(to: action, input: "Hi there!")

weak var buttonWeakReference = button
button = nil

expect(buttonWeakReference).to(beNil())
}

it("activates a generic control event") {
var called = false
let button = UIButton()
Expand Down Expand Up @@ -74,6 +87,20 @@ class BindToTests: QuickSpec {

expect(called).toEventually( beTrue() )
}

it("does not retain UIBarButtonItem") {
var barButtonItem: UIBarButtonItem? = UIBarButtonItem(barButtonSystemItem: .save, target: nil, action: nil)
let action = Action<String, String>(workFactory: { _ in
return .empty()
})
barButtonItem?.rx.bind(to: action, input: "Hi there!")

weak var barButtonItemWeakReference = barButtonItem
barButtonItem = nil

expect(barButtonItemWeakReference).to(beNil())
}

it("actives a UIRefreshControl") {
var called = false
let item = UIRefreshControl()
Expand All @@ -88,6 +115,19 @@ class BindToTests: QuickSpec {
expect(called).toEventually( beTrue() )
}

it("does not retain UIRefreshControl") {
var refreshControl: UIRefreshControl? = UIRefreshControl()
let action = Action<String, String>(workFactory: { _ in
return .empty()
})
refreshControl?.rx.bind(to: action, input: "Hi there!")

weak var refreshControlWeakReference = refreshControl
refreshControl = nil

expect(refreshControlWeakReference).to(beNil())
}

describe("unbinding") {
it("unbinds actions for UIButton") {
let button = UIButton()
Expand Down