美文网首页swift
ReactiveSwift(下)

ReactiveSwift(下)

作者: Harely | 来源:发表于2017-12-21 12:34 被阅读26次

    SignalProducer

    SignalProducer是ReactiveSwift中冷信号的实现, 是第二种发送事件的途径.

            热信号是活动着的事件发生器, 相对应的, 冷信号则是休眠中的事件发生器. 也就是说冷信号需要一个唤醒操作, 然后才能发送事件, 而这个唤醒操作就是订阅它. 因为订阅后才发送事件, 显然, 冷信号不存在时机早晚的问题. 仍以春晚举例:

            冷信号相当于春晚的视频文件而不是现场直播, 正常情况下, 视频文件肯定是不会自动播放的, 但你只要一双击, 它就被启动播放然后输出节目了.

    //1. 通过SignalProducer.init(startHandler: (Observer, Lifetime) -> Void)创建SignalProducer

    let producer = SignalProducer { (innerObserver, lifetime) in

    lifetime.observeEnded({

    print("信号无效了 你可以在这里进行一些清理工作")

    })

    //2. 向外界发送事件

    innerObserver.send(value: 1)

    innerObserver.send(value: 2)

    innerObserver.sendCompleted()

    }

    //3. 创建一个观察者封装事件处理逻辑

    let outerObserver = Signal.Observer(value: { (value) in

    print("did received value: (value)")

    })

    //4. 添加观察者到SignalProducer

    producer.start(outerObserver)

    输出: did received value: 1

    did received value: 2

    信号无效了 你可以在这里进行一些清理工作

    typealias Producer = ReactiveSwift.SignalProducer

    let producer = Producer { (innerObserver, _) in

    //没什么想清理的

    innerObserver.send(value: 1)

    innerObserver.send(value: 2)

    innerObserver.sendCompleted()

    }

    producer.startWithValues { (value) in

    print("did received value: (value)")

    }

    producer.startWithFailed(action: )

    producer.startWithResult(action: )

    producer.startWithXXX...各种便利函数

    和Signal的订阅方式如出一辙, 只是名字换了一下, Signal.observeXXX换成了SignalProducer.startXXX.

                都是事件发生器, 所以API方面Signal和SignalProducer都是一样的,上面的map, on, merge, comblinelast...等等, SignalProducer也有一份, 作用也都一样, 我就不多说了, 这里简单给两段代码说说可能遇到的坑

    func fetchData(completionHandler: (Int, Error?) -> ()) {

    print("发起网络请求")

    completionHandler(1, nil)

    }

    let producer = Producer {[unowned self] (innerObserver, _) in

    self.fetchData(completionHandler: { (data, error) in

    innerObserver.send(value: data)

    innerObserver.sendCompleted()

    })

    }

    producer.startWithValues { (value) in

    print("did received value: (value)")

    }

    producer.startWithValues { (value) in

    print("did received value: (value)")

    }

    输出: 发起网络请求

    did received value: 1

    发起网络请求

    did received value: 1

    也许你只是想两个观察者共享一次网络请求带回的Event, 但事实上这里会发生两次网络请求, 但这不是一个bug, 这是一个feature.

    SignalProducer的一个特性是, 每次被订阅就会执行一次初始化时保存的闭包.

    所以如果你有类似一次执行, 多处订阅的需求, 你应该选择Signal而不是SignalProducer. 所以, 符合需求的代码可能是这样:


    let signalTuple = NSignal.pipe()

    signalTuple.output.observeValues { (value) in

    print("did received value: (value)")

    }

    signalTuple.output.observeValues { (value) in

    print("did received value: (value)")

    }

    self.fetchData { (data, error) in

    signalTuple.input.send(value: data)

    signalTuple.input.sendCompleted()

    }

    输出: 发起网络请求

    did received value: 1

    did received value: 1

                到目前为止, 示例代码中给到的都是NoError类型的信号, 在实际开发中, 这显然是不可能的, 毕竟错误是不可避免的. 通常我们的项目会声明一个类似APIError的错误类型来表示这些错误, 所以你可能会有这样的声明:    

    structAPIError: Swift.Error {

    let code: Int

    var reason =""

    }

    typealias NSignal = ReactiveSwift.Signaltypealias 

     APISignal = ReactiveSwift.Signaltypealias

     Producer = ReactiveSwift.SignalProducertypealias

     APIProducer = ReactiveSwift.SignalProducer

    这样的声明很好, 能让ReactiveSwift写起来像RXSwift一样"简洁". 但这里需要加上下面的代码才能更好的工作:

    extension SignalProducer where Error == APIError {

    @discardableResult

    func startWithValues(_ action: @escaping (Value) -> Void) -> Disposable {

    returnstart(Signal.Observer(value: action))

    }

    }

            这是因为默认的SignalProducer是没有startWithValues函数的, ReactiveSwift会在Extension里给它加上startWithValues函数, 但是这只对NoError有效, 所以当你在自定义Error时, 请记得加上类似的代码.    

    相关文章

      网友评论

      • 起个名字好难O0:使用ReactiveSwift监听 Bool属性. 返回上一页, 会Crash,Thread 1: signal SIGABRT是为什么
        起个名字好难O0:@Harely 我找到原因了. 是因为我用的 unowned self. 这个时候self不置为nil.造成了野指针. 最后老老实实改用了 weak self
        Harely:@起个名字好难O0 在里面使用strong 进行强引用,若是用弱引用可能已释放掉了!不好意思这么久没回复你,一直在忙!
        起个名字好难O0:viewModel.responseSuccess.signal.observeValues { (success) in}
        还是viewModel.responseSuccess.signal.observeValues { [unowned self](success) in}
        要不要弱引用self. 弱引用self 会Crash

      本文标题:ReactiveSwift(下)

      本文链接:https://www.haomeiwen.com/subject/kctawxtx.html