原来 RAC 中和 Swift 平台相关的核⼼心代码被单独抽取成了了⼀一个新框架:ReactiveSwift 。
Swift 正在快速成⻓长并且成⻓长为⼀一个跨平台的语⾔言。把只和 Swift 相关的代码抽取出来后,ReactiveSwift 就 可以在其他平台上被使⽤,⽽而不不只是局限在 CocoaTouch 和 Cocoa 中。
什么是热信号和冷信号
-
热信号是主动的,不管有没有订阅者,他都会启动。如果发送当时有订阅者,就会同时接收到信号,如果没有就不会接收到消息,给订阅者发送消息不一定会收到,它可以有多个订阅者,是一对多,集合可以与订阅者共享信息
-
冷信号是被动的,只有当你订阅的时候,它才会发布消。当有不同的订阅者,消息是重新完整发送。
如何给变量添加reactive计算属性
public protocol ReactiveExtensionsProvider {
}
extension ReactiveExtensionsProvider {
/// 成员计算变量
public var reactive: Reactive<Self> {
return Reactive(self)
}
/// 静态成员计算变量
public static var reactive: Reactive<Self>.Type {
return Reactive<Self>.self
}
}
/// 定义泛型结构体
public struct Reactive<Base> {
public let base: Base
fileprivate init(_ base: Base) {
self.base = base
}
}
如何使用
struct Person {
var name = "小明"
}
extension Person:ReactiveExtensionsProvider{
}
extension Reactive where Base == Person{
func printName(){
print("Person.Name:\(base.name)")
}
}
let person = Person.init()
person.reactive.printName()//输出:Person.Name:小明
Event
extension Signal {
public enum Event {
/// 信号中的值
case value(Value)
/// 信号由于错误而终止。不会再收到其他事件。
case failed(Error)
/// 信号成功终止。 不会再收到其他事件。
case completed
/// 信号的事件产生已中断。 不会再收到其他事件。
/// 重要:此事件并不表示成功或失败信号完成。
case interrupted
/// 此事件是否为已完成事件。
public var isCompleted: Bool {
switch self {
case .completed:
return true
case .value, .failed, .interrupted:
return false
}
}
/// 此事件是否表示信号终止(即不再事件将被接收)。
public var isTerminating: Bool {
switch self {
case .value:
return false
case .failed, .completed, .interrupted:
return true
}
}
}
}
Signal
Signal是ReactiveSwift中热信号的实现,会主动将产出的事件Event向外发送, 而不会等到有人订阅后才开始发送. 这意味着如果订阅的时机晚于发送的时机, 那么订阅者是不会收到订阅时机之前的事件的.
Signal的实现
public final class Signal<Value, Error: Swift.Error>
Signal只包含一个存储属性
private let core: Core
Signal本质上只是 Core的一个壳,Signal 添加观察者,其实就是core 添加观察者,所以接下来我们主要介绍的其实是Core. 我们来看看Core的主要定义:
///信号的状态
private enum State {
// `TerminationKind` is constantly pointer-size large to keep `Signal.Core`
// allocation size independent of the actual `Value` and `Error` types.
enum TerminationKind {
case completed
case interrupted
case failed(Swift.Error)
case silent
init(_ event: Event) {
switch event {
case .value:
fatalError()
case .interrupted:
self = .interrupted
case let .failed(error):
self = .failed(error)
case .completed:
self = .completed
}
}
func materialize() -> Event? {
switch self {
case .completed:
return .completed
case .interrupted:
return .interrupted
case let .failed(error):
return .failed(error as! Error)
case .silent:
return nil
}
}
}
/// 信号还是存活的
case alive(Bag<Observer>, hasDeinitialized: Bool)
/// “信号”已收到终止事件,并且即将终止。
case terminating(Bag<Observer>, TerminationKind)
/// 信号已终止。
case terminated
}
private final class Core {
/// 与信号关联的一次性对象。
private let disposable: CompositeDisposable
///信号的状态
private var state: State
/// 状态锁,确保所有状态的同步
private let stateLock: Lock
/// 事件锁 用于确保事件在交付给观察者的过程中的同步
private let sendLock: Lock
///Core 的构造方法
fileprivate init(_ generator: (Observer, Lifetime) -> Void) {
state = .alive(Bag(), hasDeinitialized: false)
stateLock = Lock.make()
sendLock = Lock.make()
disposable = CompositeDisposable()
// The generator observer retains the `Signal` core.
generator(Observer(action: self.send, interruptsOnDeinit: true), Lifetime(disposable))
}
private func send(_ event: Event) {
//判断信号是否终止,也就是 是否发送了 .failed, .completed, .interrupted这些事件
if event.isTerminating {
// Recursive events are disallowed for `value` events, but are permitted
// for termination events. Specifically:
//
// - `interrupted`
// It can inadvertently be sent by downstream consumers as part of the
// `SignalProducer` mechanics.
//
// - `completed`
// If a downstream consumer weakly references an object, invocation of
// such consumer may cause a race condition with its weak retain against
// the last strong release of the object. If the `Lifetime` of the
// object is being referenced by an upstream `take(during:)`, a
// signal recursion might occur.
//
// So we would treat termination events specially. If it happens to
// occur while the `sendLock` is acquired, the observer call-out and
// the disposal would be delegated to the current sender, or
// occasionally one of the senders waiting on `sendLock`.
self.stateLock.lock()
if case let .alive(observers, _) = state {
self.state = .terminating(observers, .