Skip to content

Commit

Permalink
Merge pull request #49 from RxSwiftCommunity/feature/hasDisposeBag
Browse files Browse the repository at this point in the history
feature: rehabilitates the HasDisposeBag protocol
  • Loading branch information
ashfurrow authored Oct 27, 2017
2 parents d64b5ff + ab5c60f commit 88d806a
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 1 deletion.
19 changes: 18 additions & 1 deletion Demo/DemoTests/DemoTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,48 @@ import Nimble
import RxSwift
import NSObject_Rx

class DisposeBagTest: HasDisposeBag {

}

class Test: QuickSpec {
override func spec() {
it("respects setter") {
var subject = NSObject()
let disposeBag = DisposeBag()
subject.rx.disposeBag = disposeBag

let subjectProtocol = DisposeBagTest()
subjectProtocol.disposeBag = disposeBag
expect(subject.rx.disposeBag) === disposeBag
expect(subjectProtocol.disposeBag) === disposeBag
}

it("diposes when object is deallocated") {
var executed = false
var executedProtocol = false

let variable = PublishSubject<Int>()
let variableProtocol = PublishSubject<Int>()

// Force the bag to deinit (and dispose itself).
do {
let subject = NSObject()
let subjectProtocol = DisposeBagTest()

variable.subscribe(onNext: { _ in
executed = true
}).addDisposableTo(subject.rx.disposeBag)

variableProtocol.subscribe(onNext: { _ in
executedProtocol = true
}).addDisposableTo(subjectProtocol.disposeBag)
}

// Force a new value through the subscription to test its been disposed of.
variable.onNext(1)
variableProtocol.onNext(1)
expect(executed) == false
expect(executedProtocol) == false
}

it("disposes using rx.disposeBag") {
Expand Down
44 changes: 44 additions & 0 deletions HasDisposeBag.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Foundation
import RxSwift
import ObjectiveC

fileprivate var disposeBagContext: UInt8 = 0

/// each HasDisposeBag offers a unique RxSwift DisposeBag instance
public protocol HasDisposeBag: class {

/// a unique RxSwift DisposeBag instance
var disposeBag: DisposeBag { get set }
}

extension HasDisposeBag {

func synchronizedBag<T>( _ action: () -> T) -> T {
objc_sync_enter(self)
let result = action()
objc_sync_exit(self)
return result
}

public var disposeBag: DisposeBag {
get {
return synchronizedBag {
if let disposeObject = objc_getAssociatedObject(self, &disposeBagContext) as? DisposeBag {
return disposeObject
}
let disposeObject = DisposeBag()
objc_setAssociatedObject(self, &disposeBagContext, disposeObject, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
return disposeObject
}
}

set {
synchronizedBag {
objc_setAssociatedObject(self, &disposeBagContext, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
}



0 comments on commit 88d806a

Please sign in to comment.