import Foundation public final class QueueLocalObject<T: AnyObject> { public let queue: Queue private var valueRef: Unmanaged<T>? 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 with(_ f: @escaping (T) -> Void) { self.queue.async { if let valueRef = self.valueRef { let value = valueRef.takeUnretainedValue() f(value) } } } public func syncWith<R>(_ 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<R, E>(_ f: @escaping (T, Subscriber<R, E>) -> Disposable) -> Signal<R, E> { 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) } }