函数响应编程&RxSwift(一)

3 篇文章 0 订阅
2 篇文章 0 订阅

    RxSwift安装:

    CocoPod导入:

  pod 'RxSwift'
  pod 'RxCocoa'

一.函数式编程

    函数式编程是种编程范式,它需要我们将函数作为参数传递,或者作为返回值返还。我们可以通过组合不同的函数来得到想要的结果。
 

用数学表达式来表示:

函数 y = f(x) 

x参数可以是一个函数    x = f(x)    例如:2 = 1+1 = 0+2

将以上的函数作为参数传入第一个函数中

y = f(f(x))  
//例1:
//遍历数组(要求:1.首先获取 > 3的数字;2.获取的数字之后 + 1;3.所有数字中的偶数;4.可读性 清晰度)

let array = [1,2,3,4,5,6,7]

//普通处理方式:
        for num in array{
            if num > 3{
                let number = num + 1
                if (number % 2 == 0) {
                    print(number)
                }
            }
        }
//函数式:
array.filter{ $0 > 3}
     .filter{ ($0+1) % 2 == 0 }
     .forEach { print($0) }

    它使我们可以通过组合不同的方法,以及不同的函数来获取目标结果。传统的 for 循环来完成相同的逻辑,是一件多么繁琐的事情。所以函数试编程的优点是显而易见的:

  • 灵活
  • 高复用
  • 简洁
  • 易维护
  • 适应各种需求变化

二.函数响应式编程

    将函数式编程来操作序列的方式升华一下。例如:把一个按钮的点击事件看作是一个序列:

//例2:
//传统写法
var button: UIButton
...
//初始化
button = UIButton()
button.addTarget(self, action: #selector(text), for: .touchUpInside)
....
   
@objc func text() {
   print("Button clicked!")
}

   可以看出业务逻辑可功能模块分开了,随着代码量的增多,维护更新成本增加。引用RxSwift之后:

...
let bag = DisposeBag()
....

self.button.rx.tap    //序列
            .subscribe(onNext: { () in   //订阅
                print("Button clicked!")
            }, onError: { (error) in
                print("错误信息")
            }, onCompleted: {
                print("订阅完成")
            })
            .disposed(by: bag)    //销毁

 

    这里 taps 就是按钮点击事件的序列。然后我们通过打印“Button clicked!”,来对每一次点击事件做出响应。这种编程方式叫做响应式编程。我们结合函数式编程以及响应式编程就得到了函数响应式编程。通过不同的构建函数,来创建所需要的数据序列。最后通过适当的方式来响应这个序列。这就是函数响应式编程

三.RxSwift

    1.例2中,为什么button可以“.rx”?

    查看rx的源码:

/// A type that has reactive extensions.
public protocol ReactiveCompatible {    //定义了一个协议,意味着实现了协议的都会有rx
    /// Extended type
    associatedtype CompatibleType  

    /// Reactive extensions.
    static var rx: Reactive<CompatibleType>.Type { get set }

    /// Reactive extensions.
    var rx: Reactive<CompatibleType> { get set }
}

extension NSObject: ReactiveCompatible { }    //因为NSObject遵循了以上协议,所以NSObject及其子类都可以 .rx

    2.Observable - 可监听序列

  Observable 可以用于描述元素异步产生的序列,所有的事物都可以看作是序列,生活中许多事物都可以通过它来表示。

              序列图(坐标:时间,异步发生的,事件:1、2、3...)

//例3: 创建一个序列
//1:创建序列
 let ob = Observable<Any>.create { (observer) -> Disposable in
            // 3:发送信号
            obserber.onNext("????")
            obserber.onCompleted()
//            obserber.onError(NSError.init(domain: "error!", code: 10087, userInfo: nil))
            return Disposables.create()

//2:订阅信息
 let _ = ob.subscribe(onNext: { (text) in
            print("订阅到:\(text)")    //text从哪里来的?
        }, onError: { (error) in
            print("error: \(error)")    //error从哪里来的?
        }, onCompleted: {
            print("完成")
        }) {
            print("销毁")
        }

    思考:订阅信号中的onNext闭包里面的“text”、onError闭包里面的“error”从哪里来的呢?

    从订阅中心observer,一直在用的序列,序列内部的代码是不曾看到的。为什么从序列闭包里面的发出信号,订阅信号的闭包里面能够订阅到?

四.RxSwift核心逻辑

    1.源码分析

     创建序列的方法:

/**
         Creates an observable sequence from a specified subscribe method implementation.
    
         - seealso: [create operator on reactivex.io](http://reactivex.io/documentation/operators/create.html)
    
         - parameter subscribe: Implementation of the resulting observable sequence's `subscribe` method.
         - returns: The observable sequence with the specified implementation for the `subscribe` method.
         */    
public static func create(_ subscribe: @escaping (RxSwift.AnyObserver<Self.E>)
    -> Disposable) -> RxSwift.Observable<Self.E>

    源码实现:

 public static func create(_ subscribe: @escaping (AnyObserver<E>) -> Disposable) -> Observable<E> {
        return AnonymousObservable(subscribe)
    }

    查看creat的源码发现,方法返回了一个AnonymousObservable(匿名序列)。

//AnonymousObservable类
final private class AnonymousObservable<Element>: Producer<Element> {
    typealias SubscribeHandler = (AnyObserver<Element>) -> Disposable

    let _subscribeHandler: SubscribeHandler

    init(_ subscribeHandler: @escaping SubscribeHandler) {
        self._subscribeHandler = subscribeHandler    //带参数进行初始化,subscrib回调的记录,保存了这个闭包,函数式编程思想
    }

    override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
        let sink = AnonymousObservableSink(observer: observer, cancel: cancel)
        let subscription = sink.run(self)
        return (sink: sink, subscription: subscription)
    }
}

//Producer类,包含了subscribe方法
class Producer<Element> : Observable<Element> {
    override init() {
        super.init()
    }

    override func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == Element {
        if !CurrentThreadScheduler.isScheduleRequired {
            // The returned disposable needs to release all references once it was disposed.
            let disposer = SinkDisposer()
            let sinkAndSubscription = self.run(observer, cancel: disposer)    //具体的实现交给子类
            disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)

            return disposer
        }
        else {
            return CurrentThreadScheduler.instance.schedule(()) { _ in
                let disposer = SinkDisposer()
                let sinkAndSubscription = self.run(observer, cancel: disposer)    //具体的实现交给子类
                disposer.setSinkAndSubscription(sink: sinkAndSubscription.sink, subscription: sinkAndSubscription.subscription)

                return disposer
            }
        }
    }

    func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == Element {
        rxAbstractMethod()
    }
}

  

    查看订阅信息的subscribe的源码,发现,方法内创建了一个AnonymousObserver类型的observer。

    public func subscribe(onNext: ((E) -> Void)? = nil, onError: ((Swift.Error) -> Void)? = nil, onCompleted: (() -> Void)? = nil, onDisposed: (() -> Void)? = nil)
        -> Disposable {
            let disposable: Disposable
            
          ...
            
            let observer = AnonymousObserver<E> {  event in   //创建observer,event从AnonymousObserver构建而来
                
                #if DEBUG
                    synchronizationTracker.register(synchronizationErrorMessage: .default)
                    defer { synchronizationTracker.unregister() }
                #endif
                
                switch event {    //对next、error、completed、disposed四个闭包进行初始化
                case .next(let value):    //只要观察者调用了.next事件,就会调用订阅事件.onNext
                    onNext?(value)
                case .error(let error):
                    if let onError = onError {
                        onError(error)
                    }
                    else {
                        Hooks.defaultErrorHandler(callStack, error)
                    }
                    disposable.dispose()
                case .completed:
                    onCompleted?()
                    disposable.dispose()
                }
            }
            return Disposables.create(
                self.asObservable().subscribe(observer),    /*回调了当前序列(即ob)的_subscribeHandler闭包,
AnonymousObservable类里面没有subscrib方法,去他的父类Producer中查找,调用子类的实现*/
                disposable
            )
    }

//AnonymousObserver类
final class AnonymousObserver<ElementType> : ObserverBase<ElementType> {
    typealias Element = ElementType
    
    typealias EventHandler = (Event<Element>) -> Void
    
    private let _eventHandler : EventHandler
    
    init(_ eventHandler: @escaping EventHandler) {
#if TRACE_RESOURCES
        _ = Resources.incrementTotal()
#endif
        self._eventHandler = eventHandler    //保存了包含事件的闭包
    }

    override func onCore(_ event: Event<Element>) {
        return self._eventHandler(event)
    }
    
#if TRACE_RESOURCES
    deinit {
        _ = Resources.decrementTotal()
    }
#endif
}

//asObservable方法定义
 public func asObservable() -> Observable<E> {
     return self
 }

//Producer类
class Producer<Element> : Observable<Element> {
    override init() {
        super.init()
    }

    override func subscribe<O : ObserverType>(_ observer: O) -> Disposable where O.E == Element {
        if !CurrentThreadScheduler.isScheduleRequired {
        ...
}

   

 

 

 

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值