Skip to content

Commit fd9295f

Browse files
authored
Merge pull request #363 from ReactiveCocoa/remove-disposable-handle
Remove `CompositeDisposable.DisposableHandle`.
2 parents 7bbb458 + 5ae1247 commit fd9295f

File tree

4 files changed

+42
-72
lines changed

4 files changed

+42
-72
lines changed

Sources/Deprecations+Removals.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,16 @@ extension ComposableMutablePropertyProtocol {
7575
public func withValue<Result>(action: (Value) throws -> Result) rethrows -> Result { fatalError() }
7676
}
7777

78+
extension CompositeDisposable {
79+
@available(*, deprecated, message:"Use `Disposable?` instead. The typealias would be removed in a future release.")
80+
public typealias DisposableHandle = Disposable?
81+
}
82+
83+
extension Optional where Wrapped == Disposable {
84+
@available(*, unavailable, renamed:"dispose")
85+
public func remove() { fatalError() }
86+
}
87+
7888
@available(*, unavailable, renamed:"SignalProducer.timer")
7989
public func timer(interval: DispatchTimeInterval, on scheduler: DateScheduler) -> SignalProducer<Date, NoError> { fatalError() }
8090

@@ -306,7 +316,7 @@ extension Bag {
306316

307317
extension CompositeDisposable {
308318
@available(*, unavailable, renamed:"add(_:)")
309-
public func addDisposable(_ d: Disposable) -> DisposableHandle { fatalError() }
319+
public func addDisposable(_ d: Disposable) -> Disposable? { fatalError() }
310320
}
311321

312322
extension Observer {

Sources/Disposable.swift

Lines changed: 27 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -110,48 +110,6 @@ public final class CompositeDisposable: Disposable {
110110
private let disposables: Atomic<Bag<Disposable>?>
111111
private var state: UnsafeAtomicState<DisposableState>
112112

113-
/// Represents a handle to a disposable previously added to a
114-
/// `CompositeDisposable`.
115-
///
116-
/// - note: `add(_:)` method of `CompositeDisposable` creates instances of
117-
/// `DisposableHandle`.
118-
public final class DisposableHandle {
119-
private var state: UnsafeAtomicState<DisposableState>
120-
private var bagToken: Bag<Disposable>.Token?
121-
private weak var disposable: CompositeDisposable?
122-
123-
fileprivate static let empty = DisposableHandle()
124-
125-
fileprivate init() {
126-
self.state = UnsafeAtomicState(.disposed)
127-
self.bagToken = nil
128-
}
129-
130-
deinit {
131-
state.deinitialize()
132-
}
133-
134-
fileprivate init(bagToken: Bag<Disposable>.Token, disposable: CompositeDisposable) {
135-
self.state = UnsafeAtomicState(.active)
136-
self.bagToken = bagToken
137-
self.disposable = disposable
138-
}
139-
140-
/// Remove the pointed-to disposable from its `CompositeDisposable`.
141-
///
142-
/// - note: This is useful to minimize memory growth, by removing
143-
/// disposables that are no longer needed.
144-
public func remove() {
145-
if state.tryDispose(), let token = bagToken {
146-
_ = disposable?.disposables.modify {
147-
$0?.remove(using: token)
148-
}
149-
bagToken = nil
150-
disposable = nil
151-
}
152-
}
153-
}
154-
155113
public var isDisposed: Bool {
156114
return state.is(.disposed)
157115
}
@@ -202,41 +160,43 @@ public final class CompositeDisposable: Disposable {
202160
}
203161
}
204162

205-
/// Add the given disposable to the list, then return a handle which can
206-
/// be used to opaquely remove the disposable later (if desired).
163+
/// Add the given disposable to the composite.
207164
///
208165
/// - parameters:
209-
/// - d: Optional disposable.
166+
/// - disposable: A disposable.
210167
///
211-
/// - returns: An instance of `DisposableHandle` that can be used to
212-
/// opaquely remove the disposable later (if desired).
168+
/// - returns: A disposable to remove `disposable` from the composite. `nil` if the
169+
/// composite has been disposed of, `disposable` has been disposed of, or
170+
/// `disposable` is `nil`.
213171
@discardableResult
214-
public func add(_ d: Disposable?) -> DisposableHandle {
215-
guard let d = d else {
216-
return DisposableHandle.empty
172+
public func add(_ disposable: Disposable?) -> Disposable? {
173+
guard let d = disposable, !d.isDisposed, !isDisposed else {
174+
disposable?.dispose()
175+
return nil
217176
}
218177

219-
let handle: DisposableHandle? = disposables.modify {
220-
return ($0?.insert(d)).map { DisposableHandle(bagToken: $0, disposable: self) }
221-
}
178+
return disposables.modify { disposables in
179+
guard disposables != nil else { return nil }
222180

223-
if let handle = handle {
224-
return handle
225-
} else {
226-
d.dispose()
227-
return DisposableHandle.empty
181+
let token = disposables!.insert(d)
182+
return ActionDisposable { [weak self] in
183+
self?.disposables.modify {
184+
$0?.remove(using: token)
185+
}
186+
}
228187
}
229188
}
230189

231-
/// Add an ActionDisposable to the list.
190+
/// Add the given action to the composite.
232191
///
233192
/// - parameters:
234-
/// - action: A closure that will be invoked when `dispose()` is called.
193+
/// - action: A closure to be invoked when the composite is disposed of.
235194
///
236-
/// - returns: An instance of `DisposableHandle` that can be used to
237-
/// opaquely remove the disposable later (if desired).
195+
/// - returns: A disposable to remove `disposable` from the composite. `nil` if the
196+
/// composite has been disposed of, `disposable` has been disposed of, or
197+
/// `disposable` is `nil`.
238198
@discardableResult
239-
public func add(_ action: @escaping () -> Void) -> DisposableHandle {
199+
public func add(_ action: @escaping () -> Void) -> Disposable? {
240200
return add(ActionDisposable(action: action))
241201
}
242202

@@ -351,7 +311,7 @@ public final class SerialDisposable: Disposable {
351311
/// - returns: An instance of `DisposableHandle` that can be used to opaquely
352312
/// remove the disposable later (if desired).
353313
@discardableResult
354-
public func +=(lhs: CompositeDisposable, rhs: Disposable?) -> CompositeDisposable.DisposableHandle {
314+
public func +=(lhs: CompositeDisposable, rhs: Disposable?) -> Disposable? {
355315
return lhs.add(rhs)
356316
}
357317

@@ -369,7 +329,7 @@ public func +=(lhs: CompositeDisposable, rhs: Disposable?) -> CompositeDisposabl
369329
/// - returns: An instance of `DisposableHandle` that can be used to opaquely
370330
/// remove the disposable later (if desired).
371331
@discardableResult
372-
public func +=(lhs: CompositeDisposable, rhs: @escaping () -> ()) -> CompositeDisposable.DisposableHandle {
332+
public func +=(lhs: CompositeDisposable, rhs: @escaping () -> ()) -> Disposable? {
373333
return lhs.add(rhs)
374334
}
375335

@@ -387,7 +347,7 @@ public func +=(lhs: CompositeDisposable, rhs: @escaping () -> ()) -> CompositeDi
387347
/// - returns: An instance of `DisposableHandle` that can be used to opaquely
388348
/// remove the disposable later (if desired).
389349
@discardableResult
390-
public func +=(lhs: ScopedDisposable<CompositeDisposable>, rhs: Disposable?) -> CompositeDisposable.DisposableHandle {
350+
public func +=(lhs: ScopedDisposable<CompositeDisposable>, rhs: Disposable?) -> Disposable? {
391351
return lhs.inner.add(rhs)
392352
}
393353

@@ -405,6 +365,6 @@ public func +=(lhs: ScopedDisposable<CompositeDisposable>, rhs: Disposable?) ->
405365
/// - returns: An instance of `DisposableHandle` that can be used to opaquely
406366
/// remove the disposable later (if desired).
407367
@discardableResult
408-
public func +=(lhs: ScopedDisposable<CompositeDisposable>, rhs: @escaping () -> ()) -> CompositeDisposable.DisposableHandle {
368+
public func +=(lhs: ScopedDisposable<CompositeDisposable>, rhs: @escaping () -> ()) -> Disposable? {
409369
return lhs.inner.add(rhs)
410370
}

Sources/Flatten.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ extension Signal where Value: SignalProducerProtocol, Error == Value.Error {
452452
signal.observe { event in
453453
switch event {
454454
case .completed, .interrupted:
455-
handle.remove()
455+
handle?.dispose()
456456

457457
let shouldComplete: Bool = state.modify { state in
458458
state.activeCount -= 1
@@ -839,7 +839,7 @@ extension Signal where Value: SignalProducerProtocol, Error == Value.Error {
839839

840840
// Dispose all running innerSignals except winning one.
841841
if !relayDisposable.isDisposed {
842-
disposableHandle.remove()
842+
disposableHandle?.dispose()
843843
relayDisposable.dispose()
844844
}
845845

Tests/ReactiveSwiftTests/DisposableSpec.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ class DisposableSpec: QuickSpec {
7474
let handle = disposable += simpleDisposable
7575

7676
// We should be allowed to call this any number of times.
77-
handle.remove()
78-
handle.remove()
77+
handle?.dispose()
78+
handle?.dispose()
7979
expect(simpleDisposable.isDisposed) == false
8080

8181
disposable.dispose()

0 commit comments

Comments
 (0)