ReactiveCocoa中lift的使用方法

我对这个方法的理解是:转化现有的信号为我们需要的新的信号,并且在信号发出start()信号时才启动

先来看个简单的栗子吧:

    /**
     由给定的信号操作符创建一个新的信号
     */
    func liftExample() {
       let transform: Signal<Int, NoError> -> Signal<String, NoError> = {
            signal in
            return signal.map { "I have get \($0)" }
        }
        SignalProducer<Int, NoError>(value: 100)
//        .lift(transform)
            .startWithNext { print($0) }
    }

这里如果我们不加lift的话打印出来的是100,但是把lift加上的话,打印出来的是I have get 100

来看看lift方法中调用的transform里到底什么意思:把原有的<Int, NoError>类型的信号转换成<String, NoError>类型的信号---
return signal.map { "I have get ($0)" }的意思是原有的信号经过map转变成string字符串类型,并发送.

下面在写个例子--我把它步骤分解下。看其怎么一步一步实现的

//创建转换的类型--- Signal<[Int], NoError> -> Signal<[Int], NoError> 
let transform: Signal<[Int], NoError> -> Signal<[Int], NoError> = {
      //原来的信号
            originalSignal in
         //创建新的信号
            let (resultSignal, resultObserver) = Signal<[Int], NoError>.pipe()
        //原来的信号发送信号
            originalSignal.observeNext({ originalArr in
        //把原有信号中的数组中每个元素做  乘 5 再加 2 的操作,并返回一个接受此结果的新数组
                let newArr = originalArr.map { $0 * 5 + 2 }
         //新信号的观察者发送信号-----最重要一定要新信号的观察者发送信号,外界才能做出反应
                resultObserver.sendNext(newArr)
            })
       // 返回新的信号
            return resultSignal
        }
        
        SignalProducer<[Int], NoError>(value: [1, 2, 3, 4, 5])
        .lift(transform)
        .startWithNext { result in
            print(result)
        }

打印出的结果为 [7, 12, 17, 22, 27]

下面再举个我项目中有点麻烦的一个例子---

项目中需要获取城市列表,但是后台给的是两段式获取的。。即先获取获取全部的省,然后在根据省ID来获取下面的市。但是我想要是的一个数组类型---[“省名称”: [市]]。下面直接放代码

typealias CityDic = [String: [City]]
   let cityDic = MutableProperty<CityDic>(CityDic())

/**
     获取城市列表
     */
    mutating private func getCityList() {
        let transform: Signal<[City], NetRequestError> -> Signal<CityDic, NetRequestError> = {
            citysSignal in
            let (resultSignal, resultObserver) = Signal<CityDic, NetRequestError>.pipe()
            citysSignal.observe({ event in
                switch event {
                case let .Next(provinces):
      //这里获取到的是全部的省--需要再进一步获取到全部的市

                  //在这里一定要创建GCD  group,因为网络请求是异步的,如果不加入group的话,它会先直接返回结果,然后在请求网络
                    let group = dispatch_group_create()
                    var dict = CityDic()
                provinces.forEach({ (province) in
             //这里一定要在循环里面dispatch_group_enter,不能放在外面---因为一个循环就是一个网络请求
                    dispatch_group_enter(group)
                 NetHelper.sharedInstance.requestProvider
                 .request(RequestAPI.getCityList(type: CityType.city, parentId: province.id))
                 .mapResponseToObjArray(City)
                 .start({ event in
                    switch event {
                     case let .Next(value):
                        dict.updateValue(value, forKey: province.name!)
                        dispatch_group_leave(group)
                     case  let .Failed(error):
                   //这里,无论是失败还是成功,或者是其他什么。请立即退出group  ----dispatch_group_leave(group)
                        resultObserver.sendFailed(error)
                        dispatch_group_leave(group)
                     default:
                        dispatch_group_leave(group)
                        return
                        }
                      })
                    })
                    dispatch_group_notify(group, dispatch_get_main_queue(), {
                     //然后,在GCD group收到结束通知的时候,在主线程里观察者发送结果
                        resultObserver.sendNext(dict)
                    })
                default:
                    break
                }
            })
            return resultSignal
        }
        NetHelper.sharedInstance.requestProvider
        .request(RequestAPI.getCityList(type: CityType.province, parentId: nil))
        .mapResponseToObjArray(City)
        .lift(transform)
        .startWithResult { result in
            switch result {
            case let .Success(value):
                self.cityDic.value = value
            case let .Failure(error):
                print(error)
            }
        }
    }

注:这里面用到了我之前写道的 一篇文章里的内容, 使用Moya+ReactiveCocoa 进行网络请求,那篇文章里面也用到了lift,大家有兴趣的话,可以去看看http://www.jianshu.com/p/7bf635577900

这里面最主要的是要用GCD group~~而且是dispatch_group_enter(group) 以及dispatch_group_leave(group),不能用dispatch_group_async(dispatchGroup, dispatchQueue, ^(){ NSLog(@"dispatch-1"); });,因为,网络请求是一个操作,但是网络请求返回结果又是一个操作----切记切记

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139
  • 在上一篇文章中,我们对GCD有了基本的认知,知道其中一些简单的类型,和一些简单函数。这本篇文章中,我们将继续学习G...
    凌云壮志几多愁阅读 1,165评论 0 0
  • __block和__weak修饰符的区别其实是挺明显的:1.__block不管是ARC还是MRC模式下都可以使用,...
    LZM轮回阅读 3,282评论 0 6
  • 方法一: beginAnimations方法,此方法中包含有很多 setAnimation方法,具体代码可以进入该...
    南波万_阅读 406评论 0 0
  • 2017.2.1 作为一名合格的吃货的我,当然不肯放过每一次分享美食的机会了。 吃过那么多美食,我最喜爱的...
    千柚阅读 241评论 2 1