import Foundation public final class QueueLocalObject { public let queue: Queue private var valueRef: Unmanaged? public init(queue: Queue, generate: @escaping () -> T) { self.queue = queue self.queue.async { let value = generate() self.valueRef = Unmanaged.passRetained(value) } } deinit { let valueRef = self.valueRef self.queue.async { valueRef?.release() } } public func unsafeGet() -> T? { assert(self.queue.isCurrent()) return self.valueRef?.takeUnretainedValue() } public func with(_ f: @escaping (T) -> Void) { self.queue.async { if let valueRef = self.valueRef { let value = valueRef.takeUnretainedValue() f(value) } } } public func syncWith(_ f: @escaping (T) -> R) -> R { var result: R? self.queue.sync { if let valueRef = self.valueRef { let value = valueRef.takeUnretainedValue() result = f(value) } } return result! } public func signalWith(_ f: @escaping (T, Subscriber) -> Disposable) -> Signal { return Signal { [weak self] subscriber in if let strongSelf = self, let valueRef = strongSelf.valueRef { let value = valueRef.takeUnretainedValue() return f(value, subscriber) } else { return EmptyDisposable } } |> runOn(self.queue) } }