From f7e98e4d89a0044292e8fbc3098734100f3871ba Mon Sep 17 00:00:00 2001 From: Srdan Rasic Date: Wed, 14 Jun 2017 18:28:46 +0200 Subject: [PATCH] Improve logic in AtomicObserver to ensure synchronous disposing. --- ReactiveKit.podspec | 4 +-- ...FB4F14DE-1778-47BF-9AF1-A000D430FBBA.plist | 22 +++++++++++++ .../Info.plist | 31 +++++++++++++++++++ ReactiveKit/Info.plist | 2 +- Sources/Observer.swift | 23 ++++++++------ Sources/Signal.swift | 2 +- 6 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 ReactiveKit.xcodeproj/xcshareddata/xcbaselines/ECBCCDD91BEB6B9B00723476.xcbaseline/FB4F14DE-1778-47BF-9AF1-A000D430FBBA.plist diff --git a/ReactiveKit.podspec b/ReactiveKit.podspec index 69de5de..04c09c1 100644 --- a/ReactiveKit.podspec +++ b/ReactiveKit.podspec @@ -1,12 +1,12 @@ Pod::Spec.new do |s| s.name = "ReactiveKit" - s.version = "3.5.4" + s.version = "3.5.5" s.summary = "A Swift Reactive Programming Framework" s.description = "ReactiveKit is a Swift framework for reactive and functional reactive programming." s.homepage = "https://github.com/ReactiveKit/ReactiveKit" s.license = 'MIT' s.author = { "Srdan Rasic" => "srdan.rasic@gmail.com" } - s.source = { :git => "https://github.com/ReactiveKit/ReactiveKit.git", :tag => "v3.5.4" } + s.source = { :git => "https://github.com/ReactiveKit/ReactiveKit.git", :tag => "v3.5.5" } s.ios.deployment_target = '8.0' s.osx.deployment_target = '10.9' diff --git a/ReactiveKit.xcodeproj/xcshareddata/xcbaselines/ECBCCDD91BEB6B9B00723476.xcbaseline/FB4F14DE-1778-47BF-9AF1-A000D430FBBA.plist b/ReactiveKit.xcodeproj/xcshareddata/xcbaselines/ECBCCDD91BEB6B9B00723476.xcbaseline/FB4F14DE-1778-47BF-9AF1-A000D430FBBA.plist new file mode 100644 index 0000000..c22dab2 --- /dev/null +++ b/ReactiveKit.xcodeproj/xcshareddata/xcbaselines/ECBCCDD91BEB6B9B00723476.xcbaseline/FB4F14DE-1778-47BF-9AF1-A000D430FBBA.plist @@ -0,0 +1,22 @@ + + + + + classNames + + SignalTests + + testPerformance() + + com.apple.XCTPerformanceMetric_WallClockTime + + baselineAverage + 0.078778 + baselineIntegrationDisplayName + Local Baseline + + + + + + diff --git a/ReactiveKit.xcodeproj/xcshareddata/xcbaselines/ECBCCDD91BEB6B9B00723476.xcbaseline/Info.plist b/ReactiveKit.xcodeproj/xcshareddata/xcbaselines/ECBCCDD91BEB6B9B00723476.xcbaseline/Info.plist index ef8ba55..363dd77 100644 --- a/ReactiveKit.xcodeproj/xcshareddata/xcbaselines/ECBCCDD91BEB6B9B00723476.xcbaseline/Info.plist +++ b/ReactiveKit.xcodeproj/xcshareddata/xcbaselines/ECBCCDD91BEB6B9B00723476.xcbaseline/Info.plist @@ -35,6 +35,37 @@ com.apple.platform.iphonesimulator + FB4F14DE-1778-47BF-9AF1-A000D430FBBA + + localComputer + + busSpeedInMHz + 100 + cpuCount + 1 + cpuKind + Intel Core i5 + cpuSpeedInMHz + 2700 + logicalCPUCoresPerPackage + 4 + modelCode + MacBookPro12,1 + physicalCPUCoresPerPackage + 2 + platformIdentifier + com.apple.platform.macosx + + targetArchitecture + x86_64 + targetDevice + + modelCode + iPhone9,1 + platformIdentifier + com.apple.platform.iphonesimulator + + diff --git a/ReactiveKit/Info.plist b/ReactiveKit/Info.plist index 04d6ba4..9e467cf 100644 --- a/ReactiveKit/Info.plist +++ b/ReactiveKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 3.5.4 + 3.5.5 CFBundleSignature ???? CFBundleVersion diff --git a/Sources/Observer.swift b/Sources/Observer.swift index ad9f43d..09cd86b 100644 --- a/Sources/Observer.swift +++ b/Sources/Observer.swift @@ -60,27 +60,30 @@ public struct AnyObserver: ObserverProtocol { /// Observer that ensures events are sent atomically. public class AtomicObserver: ObserverProtocol { - private let observer: Observer - private let disposable: Disposable + private var observer: Observer? private let lock = NSRecursiveLock(name: "com.reactivekit.signal.atomicobserver") - private var terminated = false + private let parentDisposable: Disposable + + public private(set) var disposable: Disposable! /// Creates an observer that wraps given closure. public init(disposable: Disposable, observer: @escaping Observer) { - self.disposable = disposable self.observer = observer + self.parentDisposable = disposable + self.disposable = BlockDisposable { [weak self] in + self?.observer = nil + disposable.dispose() + } } /// Calles wrapped closure with the given element. public func on(_ event: Event) { lock.lock(); defer { lock.unlock() } - guard !disposable.isDisposed && !terminated else { return } - if event.isTerminal { - terminated = true - observer(event) - disposable.dispose() - } else { + if let observer = observer { observer(event) + if event.isTerminal { + disposable.dispose() + } } } } diff --git a/Sources/Signal.swift b/Sources/Signal.swift index 73d47ca..49eb89c 100644 --- a/Sources/Signal.swift +++ b/Sources/Signal.swift @@ -39,6 +39,6 @@ public struct Signal: SignalProtocol { let serialDisposable = SerialDisposable(otherDisposable: nil) let observer = AtomicObserver(disposable: serialDisposable, observer: observer) serialDisposable.otherDisposable = producer(observer) - return serialDisposable + return observer.disposable } }