Add new pods.

- RxSwift
- RXCocoa
This commit is contained in:
Qiu Yuzhou
2017-03-17 23:08:52 +08:00
parent 0bbc55748c
commit 24836d203a
227 changed files with 23130 additions and 572 deletions

View File

@ -0,0 +1,143 @@
//
// BehaviorSubject.swift
// RxSwift
//
// Created by Krunoslav Zaher on 5/23/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
/// Represents a value that changes over time.
///
/// Observers can subscribe to the subject to receive the last (or initial) value and all subsequent notifications.
public final class BehaviorSubject<Element>
: Observable<Element>
, SubjectType
, ObserverType
, SynchronizedUnsubscribeType
, Disposable {
public typealias SubjectObserverType = BehaviorSubject<Element>
typealias DisposeKey = Bag<AnyObserver<Element>>.KeyType
/// Indicates whether the subject has any observers
public var hasObservers: Bool {
_lock.lock(); defer { _lock.unlock() }
return _observers.count > 0
}
let _lock = NSRecursiveLock()
// state
private var _isDisposed = false
private var _value: Element
private var _observers = Bag<AnyObserver<Element>>()
private var _stoppedEvent: Event<Element>?
/// Indicates whether the subject has been disposed.
public var isDisposed: Bool {
return _isDisposed
}
/// Initializes a new instance of the subject that caches its last value and starts with the specified value.
///
/// - parameter value: Initial value sent to observers when no other value has been received by the subject yet.
public init(value: Element) {
_value = value
}
/// Gets the current value or throws an error.
///
/// - returns: Latest value.
public func value() throws -> Element {
_lock.lock(); defer { _lock.unlock() } // {
if _isDisposed {
throw RxError.disposed(object: self)
}
if let error = _stoppedEvent?.error {
// intentionally throw exception
throw error
}
else {
return _value
}
//}
}
/// Notifies all subscribed observers about next event.
///
/// - parameter event: Event to send to the observers.
public func on(_ event: Event<E>) {
_synchronized_on(event).on(event)
}
func _synchronized_on(_ event: Event<E>) -> Bag<AnyObserver<Element>> {
_lock.lock(); defer { _lock.unlock() }
if _stoppedEvent != nil || _isDisposed {
return Bag()
}
switch event {
case .next(let value):
_value = value
case .error, .completed:
_stoppedEvent = event
}
return _observers
}
/// Subscribes an observer to the subject.
///
/// - parameter observer: Observer to subscribe to the subject.
/// - returns: Disposable object that can be used to unsubscribe the observer from the subject.
public override func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == Element {
_lock.lock(); defer { _lock.unlock() }
return _synchronized_subscribe(observer)
}
func _synchronized_subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == E {
if _isDisposed {
observer.on(.error(RxError.disposed(object: self)))
return Disposables.create()
}
if let stoppedEvent = _stoppedEvent {
observer.on(stoppedEvent)
return Disposables.create()
}
let key = _observers.insert(observer.asObserver())
observer.on(.next(_value))
return SubscriptionDisposable(owner: self, key: key)
}
func synchronizedUnsubscribe(_ disposeKey: DisposeKey) {
_lock.lock(); defer { _lock.unlock() }
_synchronized_unsubscribe(disposeKey)
}
func _synchronized_unsubscribe(_ disposeKey: DisposeKey) {
if _isDisposed {
return
}
_ = _observers.removeKey(disposeKey)
}
/// Returns observer interface for subject.
public func asObserver() -> BehaviorSubject<Element> {
return self
}
/// Unsubscribe all observers and release resources.
public func dispose() {
_lock.performLocked {
_isDisposed = true
_observers.removeAll()
_stoppedEvent = nil
}
}
}

View File

@ -0,0 +1,129 @@
//
// PublishSubject.swift
// RxSwift
//
// Created by Krunoslav Zaher on 2/11/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
/// Represents an object that is both an observable sequence as well as an observer.
///
/// Each notification is broadcasted to all subscribed observers.
final public class PublishSubject<Element>
: Observable<Element>
, SubjectType
, Cancelable
, ObserverType
, SynchronizedUnsubscribeType {
public typealias SubjectObserverType = PublishSubject<Element>
typealias DisposeKey = Bag<AnyObserver<Element>>.KeyType
/// Indicates whether the subject has any observers
public var hasObservers: Bool {
_lock.lock(); defer { _lock.unlock() }
return _observers.count > 0
}
private var _lock = NSRecursiveLock()
// state
private var _isDisposed = false
private var _observers = Bag<AnyObserver<Element>>()
private var _stopped = false
private var _stoppedEvent = nil as Event<Element>?
/// Indicates whether the subject has been isDisposed.
public var isDisposed: Bool {
return _isDisposed
}
/// Creates a subject.
public override init() {
super.init()
}
/// Notifies all subscribed observers about next event.
///
/// - parameter event: Event to send to the observers.
public func on(_ event: Event<Element>) {
_synchronized_on(event).on(event)
}
func _synchronized_on(_ event: Event<E>) -> Bag<AnyObserver<Element>> {
_lock.lock(); defer { _lock.unlock() }
switch event {
case .next(_):
if _isDisposed || _stopped {
return Bag()
}
return _observers
case .completed, .error:
if _stoppedEvent == nil {
_stoppedEvent = event
_stopped = true
let observers = _observers
_observers.removeAll()
return observers
}
return Bag()
}
}
/**
Subscribes an observer to the subject.
- parameter observer: Observer to subscribe to the subject.
- returns: Disposable object that can be used to unsubscribe the observer from the subject.
*/
public override func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == Element {
_lock.lock(); defer { _lock.unlock() }
return _synchronized_subscribe(observer)
}
func _synchronized_subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == E {
if let stoppedEvent = _stoppedEvent {
observer.on(stoppedEvent)
return Disposables.create()
}
if _isDisposed {
observer.on(.error(RxError.disposed(object: self)))
return Disposables.create()
}
let key = _observers.insert(observer.asObserver())
return SubscriptionDisposable(owner: self, key: key)
}
func synchronizedUnsubscribe(_ disposeKey: DisposeKey) {
_lock.lock(); defer { _lock.unlock() }
_synchronized_unsubscribe(disposeKey)
}
func _synchronized_unsubscribe(_ disposeKey: DisposeKey) {
_ = _observers.removeKey(disposeKey)
}
/// Returns observer interface for subject.
public func asObserver() -> PublishSubject<Element> {
return self
}
/// Unsubscribe all observers and release resources.
public func dispose() {
_lock.lock(); defer { _lock.unlock() }
_synchronized_dispose()
}
final func _synchronized_dispose() {
_isDisposed = true
_observers.removeAll()
_stoppedEvent = nil
}
}

View File

@ -0,0 +1,250 @@
//
// ReplaySubject.swift
// RxSwift
//
// Created by Krunoslav Zaher on 4/14/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
/// Represents an object that is both an observable sequence as well as an observer.
///
/// Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies.
public class ReplaySubject<Element>
: Observable<Element>
, SubjectType
, ObserverType
, Disposable {
public typealias SubjectObserverType = ReplaySubject<Element>
/// Indicates whether the subject has any observers
public var hasObservers: Bool {
_lock.lock(); defer { _lock.unlock() }
return _observers.count > 0
}
fileprivate var _lock = NSRecursiveLock()
// state
fileprivate var _isDisposed = false
fileprivate var _stoppedEvent = nil as Event<Element>?
fileprivate var _observers = Bag<AnyObserver<Element>>()
typealias DisposeKey = Bag<AnyObserver<Element>>.KeyType
func unsubscribe(_ key: DisposeKey) {
abstractMethod()
}
/// Notifies all subscribed observers about next event.
///
/// - parameter event: Event to send to the observers.
public func on(_ event: Event<E>) {
abstractMethod()
}
/// Returns observer interface for subject.
public func asObserver() -> SubjectObserverType {
return self
}
/// Unsubscribe all observers and release resources.
public func dispose() {
}
/// Creates new instance of `ReplaySubject` that replays at most `bufferSize` last elements of sequence.
///
/// - parameter bufferSize: Maximal number of elements to replay to observer after subscription.
/// - returns: New instance of replay subject.
public static func create(bufferSize: Int) -> ReplaySubject<Element> {
if bufferSize == 1 {
return ReplayOne()
}
else {
return ReplayMany(bufferSize: bufferSize)
}
}
/// Creates a new instance of `ReplaySubject` that buffers all the elements of a sequence.
/// To avoid filling up memory, developer needs to make sure that the use case will only ever store a 'reasonable'
/// number of elements.
public static func createUnbounded() -> ReplaySubject<Element> {
return ReplayAll()
}
}
class ReplayBufferBase<Element>
: ReplaySubject<Element>
, SynchronizedUnsubscribeType {
func trim() {
abstractMethod()
}
func addValueToBuffer(_ value: Element) {
abstractMethod()
}
func replayBuffer(_ observer: AnyObserver<Element>) {
abstractMethod()
}
override func on(_ event: Event<Element>) {
_synchronized_on(event).on(event)
}
func _synchronized_on(_ event: Event<E>) -> Bag<AnyObserver<Element>> {
_lock.lock(); defer { _lock.unlock() }
if _isDisposed {
return Bag()
}
if _stoppedEvent != nil {
return Bag()
}
switch event {
case .next(let value):
addValueToBuffer(value)
trim()
return _observers
case .error, .completed:
_stoppedEvent = event
trim()
let observers = _observers
_observers.removeAll()
return observers
}
}
override func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == Element {
_lock.lock(); defer { _lock.unlock() }
return _synchronized_subscribe(observer)
}
func _synchronized_subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == E {
if _isDisposed {
observer.on(.error(RxError.disposed(object: self)))
return Disposables.create()
}
let AnyObserver = observer.asObserver()
replayBuffer(AnyObserver)
if let stoppedEvent = _stoppedEvent {
observer.on(stoppedEvent)
return Disposables.create()
}
else {
let key = _observers.insert(AnyObserver)
return SubscriptionDisposable(owner: self, key: key)
}
}
func synchronizedUnsubscribe(_ disposeKey: DisposeKey) {
_lock.lock(); defer { _lock.unlock() }
_synchronized_unsubscribe(disposeKey)
}
func _synchronized_unsubscribe(_ disposeKey: DisposeKey) {
if _isDisposed {
return
}
_ = _observers.removeKey(disposeKey)
}
override func dispose() {
super.dispose()
synchronizedDispose()
}
func synchronizedDispose() {
_lock.lock(); defer { _lock.unlock() }
_synchronized_dispose()
}
func _synchronized_dispose() {
_isDisposed = true
_stoppedEvent = nil
_observers.removeAll()
}
}
final class ReplayOne<Element> : ReplayBufferBase<Element> {
private var _value: Element?
override init() {
super.init()
}
override func trim() {
}
override func addValueToBuffer(_ value: Element) {
_value = value
}
override func replayBuffer(_ observer: AnyObserver<Element>) {
if let value = _value {
observer.on(.next(value))
}
}
override func _synchronized_dispose() {
super._synchronized_dispose()
_value = nil
}
}
class ReplayManyBase<Element> : ReplayBufferBase<Element> {
fileprivate var _queue: Queue<Element>
init(queueSize: Int) {
_queue = Queue(capacity: queueSize + 1)
}
override func addValueToBuffer(_ value: Element) {
_queue.enqueue(value)
}
override func replayBuffer(_ observer: AnyObserver<E>) {
for item in _queue {
observer.on(.next(item))
}
}
override func _synchronized_dispose() {
super._synchronized_dispose()
_queue = Queue(capacity: 0)
}
}
final class ReplayMany<Element> : ReplayManyBase<Element> {
private let _bufferSize: Int
init(bufferSize: Int) {
_bufferSize = bufferSize
super.init(queueSize: bufferSize)
}
override func trim() {
while _queue.count > _bufferSize {
_ = _queue.dequeue()
}
}
}
final class ReplayAll<Element> : ReplayManyBase<Element> {
init() {
super.init(queueSize: 0)
}
override func trim() {
}
}

View File

@ -0,0 +1,23 @@
//
// SubjectType.swift
// RxSwift
//
// Created by Krunoslav Zaher on 3/1/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
/// Represents an object that is both an observable sequence as well as an observer.
public protocol SubjectType : ObservableType {
/// The type of the observer that represents this subject.
///
/// Usually this type is type of subject itself, but it doesn't have to be.
associatedtype SubjectObserverType : ObserverType
/// Returns observer interface for subject.
///
/// - returns: Observer interface for subject.
func asObserver() -> SubjectObserverType
}

View File

@ -0,0 +1,61 @@
//
// Variable.swift
// RxSwift
//
// Created by Krunoslav Zaher on 3/28/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
/// Variable is a wrapper for `BehaviorSubject`.
///
/// Unlike `BehaviorSubject` it can't terminate with error, and when variable is deallocated
/// it will complete it's observable sequence (`asObservable`).
public class Variable<Element> {
public typealias E = Element
private let _subject: BehaviorSubject<Element>
private var _lock = SpinLock()
// state
private var _value: E
/// Gets or sets current value of variable.
///
/// Whenever a new value is set, all the observers are notified of the change.
///
/// Even if the newly set value is same as the old value, observers are still notified for change.
public var value: E {
get {
_lock.lock(); defer { _lock.unlock() }
return _value
}
set(newValue) {
_lock.lock()
_value = newValue
_lock.unlock()
_subject.on(.next(newValue))
}
}
/// Initializes variable with initial value.
///
/// - parameter value: Initial variable value.
public init(_ value: Element) {
_value = value
_subject = BehaviorSubject(value: value)
}
/// - returns: Canonical interface for push style sequence
public func asObservable() -> Observable<E> {
return _subject
}
deinit {
_subject.on(.completed)
}
}