Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RxSwiftとReactiveSwift 比較と動向

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

RxSwiftとReactiveSwift 比較と動向

Avatar for shinji hayashi

shinji hayashi

March 06, 2019
Tweet

More Decks by shinji hayashi

Other Decks in Technology

Transcript

  1. &SSPS someObservable .subscribe(onError: { error in guard let error =

    error as? SomeError else { return } }) .disposed(by: disposeBag) ɾ3Y4XJGU
  2. &SSPS let signalProducer = SignalProducer<Int, MyError> { innerObserver, disposable in

    innerObserver.send(value: 1) innerObserver.sendCompleted() } signalProducer .startWithResult { result in switch result { case let .success(value): print("value: \(value)") case let .failure(error): print("error: \(error)") } } ɾ3FBDUJWF4XJGU
  3. &SSPS let signalProducer = SignalProducer<Int, NoError> { innerObserver, disposable in

    innerObserver.send(value: 1) innerObserver.sendCompleted() } signalProducer .startWithValue { result in print("value: \(value)”) } } ɾ3FBDUJWF4XJGU
  4. #FIBWJPS3FMBZ.VUBCMF1SPQFSUZ #FIBWJPS3FMBZ .VUBCMF1SPQFSUZ BehaviorRelay is a wrapper for `BehaviorSubject`. Unlike

    `BehaviorSubject` it can't terminate with error or completed. A mutable property of type `Value` that allows observation of its changes.
  5. #FIBWJPS3FMBZ.VUBCMF1SPQFSUZ let behaviorRelay = BehaviorRelay(value: ["a"]) var mutableCopy = behaviorRelay.value

    mutableCopy.append(“b") behaviorRelay.accept(mutableCopy) ɾ#FIBWJPS3FMBZ let behaviorRelay = BehaviorRelay(value: ["a"]) behaviorRelay.value.append("b") ! ஋ͷΞΫηε͸WBMVFͱBDDFQU @FWFOU&MFNFOU Ͱߦ͏
  6. #FIBWJPS3FMBZ.VUBCMF1SPQFSUZ public func modify<Result>(_ action: (inout Value) throws -> Result)

    rethrows -> Result { return try box.begin { storage in defer { observer.send(value: storage.value) } return try storage.modify(action) } } public func withValue<Result>(_ action: (Value) throws -> Result) rethrows -> Result { return try box.withValue { try action($0) } } ɾ.VUBCMF1SPQFSUZ
  7. #FIBWJPS3FMBZ.VUBCMF1SPQFSUZ /// A reference counted box which holds a recursive

    lock and a value storage. /// /// The requirement of a `Value?` storage from composed properties prevents further /// implementation sharing with `MutableProperty`. private final class PropertyBox<Value> { private let lock: Lock.PthreadLock fileprivate var _value: Value fileprivate var isModifying = false internal var value: Value { lock.lock() defer { lock.unlock() } return _value } init(_ value: Value) { _value = value lock = Lock.PthreadLock(recursive: true) } func withValue<Result>(_ action: (Value) throws -> Result) rethrows -> Result { lock.lock() defer { lock.unlock() } return try action(_value) } func begin<Result>(_ action: (PropertyStorage<Value>) throws -> Result) rethrows -> Result { lock.lock() defer { lock.unlock() } return try action(PropertyStorage(self)) } } ɾ.VUBCMF1SPQFSUZ
  8. 3Y4XJGU 3PU8FJ– 4FQ •ɾCompatibility with Xcode 10.0 •ɾAdds new insert

    extension to collect and add multiple disposables to DisposeBag. •ɾAdds scan(into:accumulator:). •ɾAdds queuePriority parameter (defaults to .normal) to OperationQueueScheduler. •ɾPerformance enhancement reduces Bag dispatch inline code size by 12%. •ɾAdds customCaptureSubscriptionCallstack hook to allow custom subscription callstacks to be generated. •ɾRemove usage of Variable from Playground, Example projects and Tests. •ɾAdd XCTAssertRecordedElements to XCTest+Rx.
  9. 3Y4XJGU ɾ"EETOFXJOTFSUFYUFOTJPOUPDPMMFDUBOEBEENVMUJQMFEJTQPTBCMFTUP%JTQPTF#BH /// Convenience init allows a list of disposables

    to be gathered for disposal. public convenience init(disposing disposables: Disposable...) { self.init() self._disposables += disposables } /// Convenience init allows an array of disposables to be gathered for disposal. public convenience init(disposing disposables: [Disposable]) { self.init() self._disposables += disposables } /// Convenience function allows a list of disposables to be gathered for disposal. public func insert(_ disposables: Disposable...) { self.insert(disposables) } /// Convenience function allows an array of disposables to be gathered for disposal. public func insert(_ disposables: [Disposable]) { self._lock.lock(); defer { self._lock.unlock() } if self._isDisposed { disposables.forEach { $0.dispose() } } else { self._disposables += disposables } }
  10. 3Y4XJGU func testDisposeBagVaradicInsert() { let disposable1 = TestDisposable() let disposable2

    = TestDisposable() var disposeBag: DisposeBag? = DisposeBag() disposeBag?.insert(disposable1, disposable2) XCTAssert(disposable1.count == 0) XCTAssert(disposable2.count == 0) disposeBag = nil XCTAssert(disposable1.count == 1) XCTAssert(disposable2.count == 1) } func testDisposeBagVaradicInsertArray() { let disposable1 = TestDisposable() let disposable2 = TestDisposable() var disposeBag: DisposeBag? = DisposeBag() disposeBag?.insert([disposable1, disposable2]) XCTAssert(disposable1.count == 0) XCTAssert(disposable2.count == 0) disposeBag = nil XCTAssert(disposable1.count == 1) XCTAssert(disposable2.count == 1) } ɾ"EETOFXJOTFSUFYUFOTJPOUPDPMMFDUBOEBEENVMUJQMFEJTQPTBCMFTUP%JTQPTF#BH
  11. 3Y4XJGU ɾ"EETqueuePriorityQBSBNFUFS EFGBVMUTUP.normal UPOperationQueueScheduler public let queuePriority: Operation.QueuePriority let highPriority

    = OperationQueueScheduler( operationQueue: operationQueue, queuePriority: .high ) let lowPriority = OperationQueueScheduler( operationQueue: operationQueue, queuePriority: .low )
  12. 3Y4XJGU "UPNJD /PW •This relase introduces new framework RxAtomic that

    enables using C11 atomic primities •in RxSwift as a replacement for deprecated OSAtomic* functions.
 Carthage users will probably need to include this framework manually. •ɾUpdates deprecated OSAtomic* primitives to use C11 atomic primitives. •ɾAdds Event, SingleEvent, MaybeEvent and Recorded conditional conformance •ɹto Equatablewhere their Element is equatable on RXTest for clients that are using Swift >= 4.1. •ɾAdds string to NSTextView. •ɾConsolidates per platform frameworks to multi-platform frameworks. •ɾXcode 10.1 compatible. •
  13. 3Y4XJGU /*! @header * These are deprecated legacy interfaces for

    atomic operations. * The C11 interfaces in <stdatomic.h> resp. C++11 interfaces in <atomic> * should be used instead. * * Define OSATOMIC_USE_INLINED=1 to get inline implementations of these * interfaces in terms of the <stdatomic.h> resp. <atomic> primitives. * This is intended as a transition convenience, direct use of those primitives * is preferred. */ ɾOSAtomic
  14. 3FBDUJWF4XJGU 1.<~ bindings now works with optional left-hand-side operands. 2.(#642,

    kudos to @andersio and @Ankit-Aggarwal) ɾ$IBOHFT<~#JOEJOHT let nilTarget: BindingTarget<Int>? = nil // This is now a valid binding. Previously required manual // unwrapping in ReactiveSwift 3.x. nilTarget <~ notifications.map { $0.count }
  15. 3FBDUJWF4XJGU public enum Result<Success, Failure: Error> { case success(Success) case

    failure(Failure) } [WIP] Removing Result in favor of Swift.Result #702 /// A protocol that can be used to constrain associated types as `Result`. public protocol ResultProtocol { associatedtype Success associatedtype Failure: Swift.Error init(success: Success) init(failure: Failure) var result: Result<Success, Failure> { get } } 4XJGUBOE3FTVMUJO4UBOEBSE-JCSBSZ