Fixes problem with issues/67.

This commit is contained in:
Krunoslav Zaher 2015-07-24 16:47:49 +02:00
parent 68e028c984
commit 24dc2c6fe0
6 changed files with 112 additions and 10 deletions

View File

@ -16,7 +16,7 @@ public class ObservableBase<Element> : Observable<Element> {
let disposable = subscribeCore(ObserverOf(autoDetachObserver))
autoDetachObserver.setDisposable(disposable)
return disposable
return autoDetachObserver
}
func subscribeCore(observer: ObserverOf<Element>) -> Disposable {

View File

@ -25,9 +25,8 @@ class RefCount_<O: ObserverType> : Sink<O>, ObserverType {
self.parent.lock.performLocked {
if state.count == 0 {
let disposable = self.parent.source.connect()
self.parent.state.count = 1
self.parent.state.connectableSubscription = disposable
self.parent.state.connectableSubscription = self.parent.source.connect()
}
else {
self.parent.state.count = state.count + 1

View File

@ -9,8 +9,9 @@
import Foundation
class AutoDetachObserver<O: ObserverType> : ObserverBase<O.Element> {
private let observer : O
private var observer : O?
private let m : SingleAssignmentDisposable
private var observerLock = Lock()
init(observer: O) {
self.observer = observer
@ -24,12 +25,16 @@ class AutoDetachObserver<O: ObserverType> : ObserverBase<O.Element> {
}
override func onCore(event: Event<Element>) {
let observer = self.observerLock.calculateLocked {
return self.observer
}
switch event {
case .Next:
observer.on(event)
trySend(observer, event)
case .Completed: fallthrough
case .Error:
observer.on(event)
trySend(observer, event)
dispose()
}
}
@ -37,5 +42,8 @@ class AutoDetachObserver<O: ObserverType> : ObserverBase<O.Element> {
override func dispose() {
super.dispose()
m.dispose()
observerLock.performLocked {
self.observer = nil
}
}
}

View File

@ -0,0 +1,89 @@
//
// AnonymousObservable+Test.swift
// RxTests
//
// Created by Krunoslav Zaher on 7/24/15.
//
//
import Foundation
import RxSwift
import XCTest
class AnonymousObservableTests : RxTest {
}
extension AnonymousObservableTests {
func testAnonymousObservable_detachesOnDispose() {
var observer: ObserverOf<Int>!
let a = create { o in
observer = o
return NopDisposable.instance
} as Observable<Int>
var elements = [Int]()
let d = a >- subscribeNext { n in
elements.append(n)
}
XCTAssertEqual(elements, [])
sendNext(observer, 0)
XCTAssertEqual(elements, [0])
d.dispose()
sendNext(observer, 1)
XCTAssertEqual(elements, [0])
}
func testAnonymousObservable_detachesOnComplete() {
var observer: ObserverOf<Int>!
let a = create { o in
observer = o
return NopDisposable.instance
} as Observable<Int>
var elements = [Int]()
let d = a >- subscribeNext { n in
elements.append(n)
}
XCTAssertEqual(elements, [])
sendNext(observer, 0)
XCTAssertEqual(elements, [0])
sendCompleted(observer)
sendNext(observer, 1)
XCTAssertEqual(elements, [0])
}
func testAnonymousObservable_detachesOnError() {
var observer: ObserverOf<Int>!
let a = create { o in
observer = o
return NopDisposable.instance
} as Observable<Int>
var elements = [Int]()
let d = a >- subscribeNext { n in
elements.append(n)
}
XCTAssertEqual(elements, [])
sendNext(observer, 0)
XCTAssertEqual(elements, [0])
sendError(observer, testError)
sendNext(observer, 1)
XCTAssertEqual(elements, [0])
}
}

View File

@ -260,7 +260,7 @@ extension ObservableBindingTest {
func testReplay_DeadlockErrorAfterN() {
var nEvents = 0
let observable = concat([returnElements(0, 1, 2), failWith(testError)]) >- replay(3) >- refCount
let observable = concat([returnElements(0, 1, 2), failWith(testError)])// >- replay(3) >- refCount
let _d = observable >- subscribeError { n in
nEvents++
} >- scopedDispose

View File

@ -85,6 +85,8 @@
C8AF26EF1B499E5C00131C03 /* DelegateProxyTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AF26EE1B499E5C00131C03 /* DelegateProxyTest.swift */; };
C8AF26F01B499E5C00131C03 /* DelegateProxyTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8AF26EE1B499E5C00131C03 /* DelegateProxyTest.swift */; };
C8B5BEA11B4A6A82000D732C /* RxCocoaTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8B5BEA01B4A6A82000D732C /* RxCocoaTests.swift */; };
C8B605EC1B6260A10044410E /* AnonymousObservable+Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8B605EB1B6260A10044410E /* AnonymousObservable+Test.swift */; };
C8B605ED1B6260A10044410E /* AnonymousObservable+Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8B605EB1B6260A10044410E /* AnonymousObservable+Test.swift */; };
C8B787FA1AF55CDE00206D02 /* Observable+ConcurrencyTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8B787F91AF55CDE00206D02 /* Observable+ConcurrencyTest.swift */; };
C8CDD7CB1B52B0730043F0C5 /* RxBlocking.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C8CDD7CA1B52B0730043F0C5 /* RxBlocking.framework */; };
C8CDD7D41B52BEC40043F0C5 /* Observable+BlockingTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8CDD7D31B52BEC40043F0C5 /* Observable+BlockingTest.swift */; };
@ -143,6 +145,7 @@
C897EC491B1123DA009C2CB0 /* Observable+MultipleTest+Zip.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Observable+MultipleTest+Zip.swift"; sourceTree = "<group>"; };
C8AF26EE1B499E5C00131C03 /* DelegateProxyTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DelegateProxyTest.swift; sourceTree = "<group>"; };
C8B5BEA01B4A6A82000D732C /* RxCocoaTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RxCocoaTests.swift; sourceTree = "<group>"; };
C8B605EB1B6260A10044410E /* AnonymousObservable+Test.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AnonymousObservable+Test.swift"; sourceTree = "<group>"; };
C8B787F91AF55CDE00206D02 /* Observable+ConcurrencyTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Observable+ConcurrencyTest.swift"; sourceTree = "<group>"; };
C8CDD7CA1B52B0730043F0C5 /* RxBlocking.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = RxBlocking.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C8CDD7D31B52BEC40043F0C5 /* Observable+BlockingTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Observable+BlockingTest.swift"; sourceTree = "<group>"; };
@ -281,25 +284,26 @@
C811083F1AF50E2A001C13E4 /* Tests */ = {
isa = PBXGroup;
children = (
C8B605EB1B6260A10044410E /* AnonymousObservable+Test.swift */,
C81108401AF50E2A001C13E4 /* AssumptionsTest.swift */,
C897EC3A1B10E000009C2CB0 /* BehaviorSubjectTest.swift */,
C81108411AF50E2A001C13E4 /* ConcurrencyTest.swift */,
C8AF26EE1B499E5C00131C03 /* DelegateProxyTest.swift */,
C81108421AF50E2A001C13E4 /* DisposableTest.swift */,
C81108431AF50E2A001C13E4 /* Observable+AggregateTest.swift */,
C81108441AF50E2A001C13E4 /* Observable+BindingTest.swift */,
C8CDD7D31B52BEC40043F0C5 /* Observable+BlockingTest.swift */,
C8B787F91AF55CDE00206D02 /* Observable+ConcurrencyTest.swift */,
C81108471AF50E2A001C13E4 /* Observable+MultipleTest.swift */,
C81108451AF50E2A001C13E4 /* Observable+MultipleTest+CombineLatest.swift */,
C81108461AF50E2A001C13E4 /* Observable+MultipleTest+CombineLatest.tt */,
C897EC491B1123DA009C2CB0 /* Observable+MultipleTest+Zip.swift */,
C897EC461B112070009C2CB0 /* Observable+MultipleTest+Zip.tt */,
C81108471AF50E2A001C13E4 /* Observable+MultipleTest.swift */,
C81108481AF50E2A001C13E4 /* Observable+SingleTest.swift */,
C81108491AF50E2A001C13E4 /* Observable+StandardSequenceOperatorsTest.swift */,
C811084A1AF50E2A001C13E4 /* Observable+TimeTest.swift */,
C811084B1AF50E2A001C13E4 /* QueueTests.swift */,
C814CEA21AF5622600E98087 /* VariableTest.swift */,
C897EC3A1B10E000009C2CB0 /* BehaviorSubjectTest.swift */,
C8AF26EE1B499E5C00131C03 /* DelegateProxyTest.swift */,
);
path = Tests;
sourceTree = "<group>";
@ -435,6 +439,7 @@
C81108521AF50E2A001C13E4 /* MockObserver.swift in Sources */,
C8633AE51B0A9FF300375D60 /* KVOObservableTests.swift in Sources */,
C811085C1AF50E2A001C13E4 /* TestExtensions.swift in Sources */,
C8B605EC1B6260A10044410E /* AnonymousObservable+Test.swift in Sources */,
C811085D1AF50E2A001C13E4 /* AssumptionsTest.swift in Sources */,
C81108501AF50E2A001C13E4 /* ConnectableObservable.swift in Sources */,
C814CEA31AF5622600E98087 /* VariableTest.swift in Sources */,
@ -466,6 +471,7 @@
C88BB8A01B07E64B0064D411 /* Observable+StandardSequenceOperatorsTest.swift in Sources */,
C88BB8A11B07E64B0064D411 /* Observable+MultipleTest.swift in Sources */,
C81CC92C1B513FD400915606 /* NSObject+RxTests.swift in Sources */,
C8B605ED1B6260A10044410E /* AnonymousObservable+Test.swift in Sources */,
C88BB8A21B07E64B0064D411 /* ColdObservable.swift in Sources */,
C88BB8A31B07E64B0064D411 /* HotObservable.swift in Sources */,
C8FDC5F91B2B5B7E0065F8D9 /* ElementIndexPair.swift in Sources */,