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

RxSwiftとReactiveSwift 比較と動向

RxSwiftとReactiveSwift 比較と動向

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