ReactiveSwift 学习笔记

本文是关于ReactiveSwift的学习笔记,重点探讨了热信号与冷信号的概念,包括热信号的主动发送特性及Signal的实现,以及冷信号的被动触发和SignalProducer的使用。
摘要由CSDN通过智能技术生成

ReactiveSwift的GitHub地址

官方文档

原来 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, .
ReactiveSwift 是出自 ReactiveCocoa 小组的纯 Swift 风格 FRP。 ReactiveSwift 提供了可组合、可声明以及灵活的原语,建立在时间流的大概念之下。这些原语可用于统一展现通用 Cocoa 以及泛型编程模式,这些都是观察者的行为基础。例如委派模式、回调闭包、通知、控制动作、响应者链事件、Future/Promise 以及 K/V 的监控。所有的这些不同的机制都使用相同的方法进行呈现,可以很方便的将这些组合在一起,更少的意大利面条式的代码以及状态来弥补其中的缝隙。示例代码:// Purchase from the vending machine with a specific option. vendingMachine.purchase     .apply(snackId)     .startWithResult { result         switch result {         case let .success(snack):             print("Snack: \(snack)")         case let .failure(error):             // Out of stock? Insufficient fund?             print("Transaction aborted: \(error)")         }     } // The vending machine. class VendingMachine {     let purchase: Action<Int, Snack, VendingMachineError>     let coins: MutableProperty<Int>     // The vending machine is connected with a sales recorder.     init(_ salesRecorder: SalesRecorder) {         coins = MutableProperty(0)         purchase = Action(state: coins, enabledIf: { $0 > 0 }) { coins, snackId in             return SignalProducer { observer, _ in                 // The sales magic happens here.                 // Fetch a snack based on its id             }         }         // The sales recorders are notified for any successful sales.         purchase.values.observeValues(salesRecorder.record)     } }编者注:函数响应式编程(Functional Reactive Programming:FRP)是一种和事件流有关的编程方式,其角度类似EventSoucing,关注导致状态值改变的行为事件,一系列事件组成了事件流。FRP是更加有效率地处理事件流,而无需显式去管理状态。具体来说,FRP包括两个核心观点:事件流,离散事件序列属性properties, 代表模型连续的值。一系列事件是导致属性值发生变化的原因。FRP非常类似于GOF的观察者模式。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值